diff --git a/auth/client/pom.xml b/auth/client/pom.xml index 7426bf656..eadbd439c 100644 --- a/auth/client/pom.xml +++ b/auth/client/pom.xml @@ -13,25 +13,38 @@ - org.platformlayer - platformlayer-shared-utils + com.fathomdb + fathomdb-http - - org.jvnet.jaxb2.maven2 - maven-jaxb2-plugin + org.codehaus.mojo + jaxb2-maven-plugin + 1.5 src/main/schemas + src/generated/xjc + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.7 + process-sources + + + ${basedir}/src/generated/xjc + + - generate + add-source diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/Access.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/Access.java new file mode 100644 index 000000000..d81f734b0 --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/Access.java @@ -0,0 +1,103 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for access complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="access">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="token" type="{http://platformlayer.org/auth/v1.0}token" minOccurs="0"/>
+ *         <element name="projects" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "access", propOrder = { + "token", + "projects" +}) +public class Access { + + protected Token token; + @XmlElement(nillable = true) + protected List projects; + + /** + * Gets the value of the token property. + * + * @return + * possible object is + * {@link Token } + * + */ + public Token getToken() { + return token; + } + + /** + * Sets the value of the token property. + * + * @param value + * allowed object is + * {@link Token } + * + */ + public void setToken(Token value) { + this.token = value; + } + + /** + * Gets the value of the projects property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the projects property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getProjects().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link String } + * + * + */ + public List getProjects() { + if (projects == null) { + projects = new ArrayList(); + } + return this.projects; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/Auth.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/Auth.java new file mode 100644 index 000000000..f63a69f40 --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/Auth.java @@ -0,0 +1,148 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for auth complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="auth">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="passwordCredentials" type="{http://platformlayer.org/auth/v1.0}passwordCredentials" minOccurs="0"/>
+ *         <element name="certificateCredentials" type="{http://platformlayer.org/auth/v1.0}certificateCredentials" minOccurs="0"/>
+ *         <element name="token" type="{http://platformlayer.org/auth/v1.0}token" minOccurs="0"/>
+ *         <element name="user" type="{http://platformlayer.org/auth/v1.0}userValidation" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "auth", propOrder = { + "passwordCredentials", + "certificateCredentials", + "token", + "user" +}) +public class Auth { + + protected PasswordCredentials passwordCredentials; + protected CertificateCredentials certificateCredentials; + protected Token token; + protected UserValidation user; + + /** + * Gets the value of the passwordCredentials property. + * + * @return + * possible object is + * {@link PasswordCredentials } + * + */ + public PasswordCredentials getPasswordCredentials() { + return passwordCredentials; + } + + /** + * Sets the value of the passwordCredentials property. + * + * @param value + * allowed object is + * {@link PasswordCredentials } + * + */ + public void setPasswordCredentials(PasswordCredentials value) { + this.passwordCredentials = value; + } + + /** + * Gets the value of the certificateCredentials property. + * + * @return + * possible object is + * {@link CertificateCredentials } + * + */ + public CertificateCredentials getCertificateCredentials() { + return certificateCredentials; + } + + /** + * Sets the value of the certificateCredentials property. + * + * @param value + * allowed object is + * {@link CertificateCredentials } + * + */ + public void setCertificateCredentials(CertificateCredentials value) { + this.certificateCredentials = value; + } + + /** + * Gets the value of the token property. + * + * @return + * possible object is + * {@link Token } + * + */ + public Token getToken() { + return token; + } + + /** + * Sets the value of the token property. + * + * @param value + * allowed object is + * {@link Token } + * + */ + public void setToken(Token value) { + this.token = value; + } + + /** + * Gets the value of the user property. + * + * @return + * possible object is + * {@link UserValidation } + * + */ + public UserValidation getUser() { + return user; + } + + /** + * Sets the value of the user property. + * + * @param value + * allowed object is + * {@link UserValidation } + * + */ + public void setUser(UserValidation value) { + this.user = value; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/AuthenticateRequest.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/AuthenticateRequest.java new file mode 100644 index 000000000..3219d0ef8 --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/AuthenticateRequest.java @@ -0,0 +1,67 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for authenticateRequest complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="authenticateRequest">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{http://platformlayer.org/auth/v1.0}auth" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "authenticateRequest", propOrder = { + "auth" +}) +public class AuthenticateRequest { + + protected Auth auth; + + /** + * Gets the value of the auth property. + * + * @return + * possible object is + * {@link Auth } + * + */ + public Auth getAuth() { + return auth; + } + + /** + * Sets the value of the auth property. + * + * @param value + * allowed object is + * {@link Auth } + * + */ + public void setAuth(Auth value) { + this.auth = value; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/AuthenticateResponse.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/AuthenticateResponse.java new file mode 100644 index 000000000..3c8429a0e --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/AuthenticateResponse.java @@ -0,0 +1,119 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for authenticateResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="authenticateResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{http://platformlayer.org/auth/v1.0}access" minOccurs="0"/>
+ *         <element name="challenge" type="{http://www.w3.org/2001/XMLSchema}base64Binary" minOccurs="0"/>
+ *         <element name="statusCode" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "authenticateResponse", propOrder = { + "access", + "challenge", + "statusCode" +}) +public class AuthenticateResponse { + + protected Access access; + protected byte[] challenge; + protected Integer statusCode; + + /** + * Gets the value of the access property. + * + * @return + * possible object is + * {@link Access } + * + */ + public Access getAccess() { + return access; + } + + /** + * Sets the value of the access property. + * + * @param value + * allowed object is + * {@link Access } + * + */ + public void setAccess(Access value) { + this.access = value; + } + + /** + * Gets the value of the challenge property. + * + * @return + * possible object is + * byte[] + */ + public byte[] getChallenge() { + return challenge; + } + + /** + * Sets the value of the challenge property. + * + * @param value + * allowed object is + * byte[] + */ + public void setChallenge(byte[] value) { + this.challenge = ((byte[]) value); + } + + /** + * Gets the value of the statusCode property. + * + * @return + * possible object is + * {@link Integer } + * + */ + public Integer getStatusCode() { + return statusCode; + } + + /** + * Sets the value of the statusCode property. + * + * @param value + * allowed object is + * {@link Integer } + * + */ + public void setStatusCode(Integer value) { + this.statusCode = value; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/CertificateChainInfo.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/CertificateChainInfo.java new file mode 100644 index 000000000..4c5dfe35d --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/CertificateChainInfo.java @@ -0,0 +1,76 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for certificateChainInfo complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="certificateChainInfo">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="certificates" type="{http://platformlayer.org/auth/v1.0}certificateInfo" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "certificateChainInfo", propOrder = { + "certificates" +}) +public class CertificateChainInfo { + + @XmlElement(nillable = true) + protected List certificates; + + /** + * Gets the value of the certificates property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the certificates property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getCertificates().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link CertificateInfo } + * + * + */ + public List getCertificates() { + if (certificates == null) { + certificates = new ArrayList(); + } + return this.certificates; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/CertificateCredentials.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/CertificateCredentials.java new file mode 100644 index 000000000..4bfed3d3c --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/CertificateCredentials.java @@ -0,0 +1,92 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for certificateCredentials complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="certificateCredentials">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="username" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="challengeResponse" type="{http://www.w3.org/2001/XMLSchema}base64Binary" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "certificateCredentials", propOrder = { + "username", + "challengeResponse" +}) +public class CertificateCredentials { + + protected String username; + protected byte[] challengeResponse; + + /** + * Gets the value of the username property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getUsername() { + return username; + } + + /** + * Sets the value of the username property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setUsername(String value) { + this.username = value; + } + + /** + * Gets the value of the challengeResponse property. + * + * @return + * possible object is + * byte[] + */ + public byte[] getChallengeResponse() { + return challengeResponse; + } + + /** + * Sets the value of the challengeResponse property. + * + * @param value + * allowed object is + * byte[] + */ + public void setChallengeResponse(byte[] value) { + this.challengeResponse = ((byte[]) value); + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/CertificateInfo.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/CertificateInfo.java new file mode 100644 index 000000000..2fafb6d27 --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/CertificateInfo.java @@ -0,0 +1,121 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for certificateInfo complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="certificateInfo">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="publicKeyHash" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="publicKey" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="subjectDN" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "certificateInfo", propOrder = { + "publicKeyHash", + "publicKey", + "subjectDN" +}) +public class CertificateInfo { + + protected String publicKeyHash; + protected String publicKey; + protected String subjectDN; + + /** + * Gets the value of the publicKeyHash property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPublicKeyHash() { + return publicKeyHash; + } + + /** + * Sets the value of the publicKeyHash property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPublicKeyHash(String value) { + this.publicKeyHash = value; + } + + /** + * Gets the value of the publicKey property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPublicKey() { + return publicKey; + } + + /** + * Sets the value of the publicKey property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPublicKey(String value) { + this.publicKey = value; + } + + /** + * Gets the value of the subjectDN property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSubjectDN() { + return subjectDN; + } + + /** + * Sets the value of the subjectDN property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSubjectDN(String value) { + this.subjectDN = value; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/CheckServiceAccessRequest.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/CheckServiceAccessRequest.java new file mode 100644 index 000000000..6fec971f9 --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/CheckServiceAccessRequest.java @@ -0,0 +1,67 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for checkServiceAccessRequest complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="checkServiceAccessRequest">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="chain" type="{http://platformlayer.org/auth/v1.0}certificateChainInfo" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "checkServiceAccessRequest", propOrder = { + "chain" +}) +public class CheckServiceAccessRequest { + + protected CertificateChainInfo chain; + + /** + * Gets the value of the chain property. + * + * @return + * possible object is + * {@link CertificateChainInfo } + * + */ + public CertificateChainInfo getChain() { + return chain; + } + + /** + * Sets the value of the chain property. + * + * @param value + * allowed object is + * {@link CertificateChainInfo } + * + */ + public void setChain(CertificateChainInfo value) { + this.chain = value; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/CheckServiceAccessResponse.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/CheckServiceAccessResponse.java new file mode 100644 index 000000000..ec0fbf3e8 --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/CheckServiceAccessResponse.java @@ -0,0 +1,67 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for checkServiceAccessResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="checkServiceAccessResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="serviceAccount" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "checkServiceAccessResponse", propOrder = { + "serviceAccount" +}) +public class CheckServiceAccessResponse { + + protected String serviceAccount; + + /** + * Gets the value of the serviceAccount property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getServiceAccount() { + return serviceAccount; + } + + /** + * Sets the value of the serviceAccount property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setServiceAccount(String value) { + this.serviceAccount = value; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/ObjectFactory.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/ObjectFactory.java new file mode 100644 index 000000000..1c034cae2 --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/ObjectFactory.java @@ -0,0 +1,368 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlElementDecl; +import javax.xml.bind.annotation.XmlRegistry; +import javax.xml.namespace.QName; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the org.platformlayer.auth.v1 package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + private final static QName _SignCertificateRequest_QNAME = new QName("http://platformlayer.org/auth/v1.0", "signCertificateRequest"); + private final static QName _CheckServiceAccessResponse_QNAME = new QName("http://platformlayer.org/auth/v1.0", "checkServiceAccessResponse"); + private final static QName _CheckServiceAccessRequest_QNAME = new QName("http://platformlayer.org/auth/v1.0", "checkServiceAccessRequest"); + private final static QName _Access_QNAME = new QName("http://platformlayer.org/auth/v1.0", "access"); + private final static QName _ValidateTokenResponse_QNAME = new QName("http://platformlayer.org/auth/v1.0", "validateTokenResponse"); + private final static QName _SignCertificateResponse_QNAME = new QName("http://platformlayer.org/auth/v1.0", "signCertificateResponse"); + private final static QName _Roles_QNAME = new QName("http://platformlayer.org/auth/v1.0", "roles"); + private final static QName _RegistrationRequest_QNAME = new QName("http://platformlayer.org/auth/v1.0", "registrationRequest"); + private final static QName _RegistrationResponse_QNAME = new QName("http://platformlayer.org/auth/v1.0", "registrationResponse"); + private final static QName _Auth_QNAME = new QName("http://platformlayer.org/auth/v1.0", "auth"); + private final static QName _ValidateAccess_QNAME = new QName("http://platformlayer.org/auth/v1.0", "validateAccess"); + private final static QName _CertificateChainInfo_QNAME = new QName("http://platformlayer.org/auth/v1.0", "certificateChainInfo"); + private final static QName _User_QNAME = new QName("http://platformlayer.org/auth/v1.0", "user"); + private final static QName _AuthenticateResponse_QNAME = new QName("http://platformlayer.org/auth/v1.0", "authenticateResponse"); + private final static QName _AuthenticateRequest_QNAME = new QName("http://platformlayer.org/auth/v1.0", "authenticateRequest"); + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org.platformlayer.auth.v1 + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link PasswordCredentials } + * + */ + public PasswordCredentials createPasswordCredentials() { + return new PasswordCredentials(); + } + + /** + * Create an instance of {@link AuthenticateResponse } + * + */ + public AuthenticateResponse createAuthenticateResponse() { + return new AuthenticateResponse(); + } + + /** + * Create an instance of {@link RegistrationRequest } + * + */ + public RegistrationRequest createRegistrationRequest() { + return new RegistrationRequest(); + } + + /** + * Create an instance of {@link CertificateInfo } + * + */ + public CertificateInfo createCertificateInfo() { + return new CertificateInfo(); + } + + /** + * Create an instance of {@link Access } + * + */ + public Access createAccess() { + return new Access(); + } + + /** + * Create an instance of {@link ValidateTokenResponse } + * + */ + public ValidateTokenResponse createValidateTokenResponse() { + return new ValidateTokenResponse(); + } + + /** + * Create an instance of {@link ValidateAccess } + * + */ + public ValidateAccess createValidateAccess() { + return new ValidateAccess(); + } + + /** + * Create an instance of {@link UserValidation } + * + */ + public UserValidation createUserValidation() { + return new UserValidation(); + } + + /** + * Create an instance of {@link Token } + * + */ + public Token createToken() { + return new Token(); + } + + /** + * Create an instance of {@link RegistrationResponse } + * + */ + public RegistrationResponse createRegistrationResponse() { + return new RegistrationResponse(); + } + + /** + * Create an instance of {@link ProjectValidation } + * + */ + public ProjectValidation createProjectValidation() { + return new ProjectValidation(); + } + + /** + * Create an instance of {@link User } + * + */ + public User createUser() { + return new User(); + } + + /** + * Create an instance of {@link CertificateChainInfo } + * + */ + public CertificateChainInfo createCertificateChainInfo() { + return new CertificateChainInfo(); + } + + /** + * Create an instance of {@link CertificateCredentials } + * + */ + public CertificateCredentials createCertificateCredentials() { + return new CertificateCredentials(); + } + + /** + * Create an instance of {@link RoleList } + * + */ + public RoleList createRoleList() { + return new RoleList(); + } + + /** + * Create an instance of {@link SignCertificateRequest } + * + */ + public SignCertificateRequest createSignCertificateRequest() { + return new SignCertificateRequest(); + } + + /** + * Create an instance of {@link CheckServiceAccessRequest } + * + */ + public CheckServiceAccessRequest createCheckServiceAccessRequest() { + return new CheckServiceAccessRequest(); + } + + /** + * Create an instance of {@link Role } + * + */ + public Role createRole() { + return new Role(); + } + + /** + * Create an instance of {@link SignCertificateResponse } + * + */ + public SignCertificateResponse createSignCertificateResponse() { + return new SignCertificateResponse(); + } + + /** + * Create an instance of {@link AuthenticateRequest } + * + */ + public AuthenticateRequest createAuthenticateRequest() { + return new AuthenticateRequest(); + } + + /** + * Create an instance of {@link Auth } + * + */ + public Auth createAuth() { + return new Auth(); + } + + /** + * Create an instance of {@link CheckServiceAccessResponse } + * + */ + public CheckServiceAccessResponse createCheckServiceAccessResponse() { + return new CheckServiceAccessResponse(); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link SignCertificateRequest }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://platformlayer.org/auth/v1.0", name = "signCertificateRequest") + public JAXBElement createSignCertificateRequest(SignCertificateRequest value) { + return new JAXBElement(_SignCertificateRequest_QNAME, SignCertificateRequest.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link CheckServiceAccessResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://platformlayer.org/auth/v1.0", name = "checkServiceAccessResponse") + public JAXBElement createCheckServiceAccessResponse(CheckServiceAccessResponse value) { + return new JAXBElement(_CheckServiceAccessResponse_QNAME, CheckServiceAccessResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link CheckServiceAccessRequest }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://platformlayer.org/auth/v1.0", name = "checkServiceAccessRequest") + public JAXBElement createCheckServiceAccessRequest(CheckServiceAccessRequest value) { + return new JAXBElement(_CheckServiceAccessRequest_QNAME, CheckServiceAccessRequest.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Access }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://platformlayer.org/auth/v1.0", name = "access") + public JAXBElement createAccess(Access value) { + return new JAXBElement(_Access_QNAME, Access.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link ValidateTokenResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://platformlayer.org/auth/v1.0", name = "validateTokenResponse") + public JAXBElement createValidateTokenResponse(ValidateTokenResponse value) { + return new JAXBElement(_ValidateTokenResponse_QNAME, ValidateTokenResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link SignCertificateResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://platformlayer.org/auth/v1.0", name = "signCertificateResponse") + public JAXBElement createSignCertificateResponse(SignCertificateResponse value) { + return new JAXBElement(_SignCertificateResponse_QNAME, SignCertificateResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link RoleList }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://platformlayer.org/auth/v1.0", name = "roles") + public JAXBElement createRoles(RoleList value) { + return new JAXBElement(_Roles_QNAME, RoleList.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link RegistrationRequest }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://platformlayer.org/auth/v1.0", name = "registrationRequest") + public JAXBElement createRegistrationRequest(RegistrationRequest value) { + return new JAXBElement(_RegistrationRequest_QNAME, RegistrationRequest.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link RegistrationResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://platformlayer.org/auth/v1.0", name = "registrationResponse") + public JAXBElement createRegistrationResponse(RegistrationResponse value) { + return new JAXBElement(_RegistrationResponse_QNAME, RegistrationResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Auth }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://platformlayer.org/auth/v1.0", name = "auth") + public JAXBElement createAuth(Auth value) { + return new JAXBElement(_Auth_QNAME, Auth.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link ValidateAccess }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://platformlayer.org/auth/v1.0", name = "validateAccess") + public JAXBElement createValidateAccess(ValidateAccess value) { + return new JAXBElement(_ValidateAccess_QNAME, ValidateAccess.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link CertificateChainInfo }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://platformlayer.org/auth/v1.0", name = "certificateChainInfo") + public JAXBElement createCertificateChainInfo(CertificateChainInfo value) { + return new JAXBElement(_CertificateChainInfo_QNAME, CertificateChainInfo.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link User }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://platformlayer.org/auth/v1.0", name = "user") + public JAXBElement createUser(User value) { + return new JAXBElement(_User_QNAME, User.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link AuthenticateResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://platformlayer.org/auth/v1.0", name = "authenticateResponse") + public JAXBElement createAuthenticateResponse(AuthenticateResponse value) { + return new JAXBElement(_AuthenticateResponse_QNAME, AuthenticateResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link AuthenticateRequest }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://platformlayer.org/auth/v1.0", name = "authenticateRequest") + public JAXBElement createAuthenticateRequest(AuthenticateRequest value) { + return new JAXBElement(_AuthenticateRequest_QNAME, AuthenticateRequest.class, null, value); + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/PasswordCredentials.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/PasswordCredentials.java new file mode 100644 index 000000000..f4621cbf8 --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/PasswordCredentials.java @@ -0,0 +1,94 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for passwordCredentials complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="passwordCredentials">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="username" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="password" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "passwordCredentials", propOrder = { + "username", + "password" +}) +public class PasswordCredentials { + + protected String username; + protected String password; + + /** + * Gets the value of the username property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getUsername() { + return username; + } + + /** + * Sets the value of the username property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setUsername(String value) { + this.username = value; + } + + /** + * Gets the value of the password property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPassword() { + return password; + } + + /** + * Sets the value of the password property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPassword(String value) { + this.password = value; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/ProjectValidation.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/ProjectValidation.java new file mode 100644 index 000000000..bcbff09ea --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/ProjectValidation.java @@ -0,0 +1,155 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for projectValidation complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="projectValidation">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="id" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="secret" type="{http://www.w3.org/2001/XMLSchema}base64Binary" minOccurs="0"/>
+ *         <element name="roles" type="{http://platformlayer.org/auth/v1.0}role" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "projectValidation", propOrder = { + "id", + "name", + "secret", + "roles" +}) +public class ProjectValidation { + + protected String id; + protected String name; + protected byte[] secret; + @XmlElement(nillable = true) + protected List roles; + + /** + * Gets the value of the id property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getId() { + return id; + } + + /** + * Sets the value of the id property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setId(String value) { + this.id = value; + } + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the secret property. + * + * @return + * possible object is + * byte[] + */ + public byte[] getSecret() { + return secret; + } + + /** + * Sets the value of the secret property. + * + * @param value + * allowed object is + * byte[] + */ + public void setSecret(byte[] value) { + this.secret = ((byte[]) value); + } + + /** + * Gets the value of the roles property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the roles property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getRoles().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Role } + * + * + */ + public List getRoles() { + if (roles == null) { + roles = new ArrayList(); + } + return this.roles; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/RegistrationRequest.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/RegistrationRequest.java new file mode 100644 index 000000000..cf5c401ed --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/RegistrationRequest.java @@ -0,0 +1,94 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for registrationRequest complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="registrationRequest">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="username" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="password" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "registrationRequest", propOrder = { + "username", + "password" +}) +public class RegistrationRequest { + + protected String username; + protected String password; + + /** + * Gets the value of the username property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getUsername() { + return username; + } + + /** + * Sets the value of the username property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setUsername(String value) { + this.username = value; + } + + /** + * Gets the value of the password property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPassword() { + return password; + } + + /** + * Sets the value of the password property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPassword(String value) { + this.password = value; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/RegistrationResponse.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/RegistrationResponse.java new file mode 100644 index 000000000..55a8a9eeb --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/RegistrationResponse.java @@ -0,0 +1,94 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for registrationResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="registrationResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element ref="{http://platformlayer.org/auth/v1.0}access" minOccurs="0"/>
+ *         <element name="errorMessage" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "registrationResponse", propOrder = { + "access", + "errorMessage" +}) +public class RegistrationResponse { + + protected Access access; + protected String errorMessage; + + /** + * Gets the value of the access property. + * + * @return + * possible object is + * {@link Access } + * + */ + public Access getAccess() { + return access; + } + + /** + * Sets the value of the access property. + * + * @param value + * allowed object is + * {@link Access } + * + */ + public void setAccess(Access value) { + this.access = value; + } + + /** + * Gets the value of the errorMessage property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getErrorMessage() { + return errorMessage; + } + + /** + * Sets the value of the errorMessage property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setErrorMessage(String value) { + this.errorMessage = value; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/Role.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/Role.java new file mode 100644 index 000000000..6fb581ca3 --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/Role.java @@ -0,0 +1,67 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for role complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="role">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "role", propOrder = { + "name" +}) +public class Role { + + protected String name; + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/RoleList.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/RoleList.java new file mode 100644 index 000000000..8d2f72551 --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/RoleList.java @@ -0,0 +1,74 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for roleList complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="roleList">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="role" type="{http://platformlayer.org/auth/v1.0}role" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "roleList", propOrder = { + "role" +}) +public class RoleList { + + protected List role; + + /** + * Gets the value of the role property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the role property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getRole().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Role } + * + * + */ + public List getRole() { + if (role == null) { + role = new ArrayList(); + } + return this.role; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/SignCertificateRequest.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/SignCertificateRequest.java new file mode 100644 index 000000000..0ed266822 --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/SignCertificateRequest.java @@ -0,0 +1,119 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for signCertificateRequest complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="signCertificateRequest">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="project" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="csr" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="projectSecret" type="{http://www.w3.org/2001/XMLSchema}base64Binary" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "signCertificateRequest", propOrder = { + "project", + "csr", + "projectSecret" +}) +public class SignCertificateRequest { + + protected String project; + protected String csr; + protected byte[] projectSecret; + + /** + * Gets the value of the project property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getProject() { + return project; + } + + /** + * Sets the value of the project property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setProject(String value) { + this.project = value; + } + + /** + * Gets the value of the csr property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getCsr() { + return csr; + } + + /** + * Sets the value of the csr property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setCsr(String value) { + this.csr = value; + } + + /** + * Gets the value of the projectSecret property. + * + * @return + * possible object is + * byte[] + */ + public byte[] getProjectSecret() { + return projectSecret; + } + + /** + * Sets the value of the projectSecret property. + * + * @param value + * allowed object is + * byte[] + */ + public void setProjectSecret(byte[] value) { + this.projectSecret = ((byte[]) value); + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/SignCertificateResponse.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/SignCertificateResponse.java new file mode 100644 index 000000000..f74036f7a --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/SignCertificateResponse.java @@ -0,0 +1,76 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for signCertificateResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="signCertificateResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="certificates" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "signCertificateResponse", propOrder = { + "certificates" +}) +public class SignCertificateResponse { + + @XmlElement(nillable = true) + protected List certificates; + + /** + * Gets the value of the certificates property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the certificates property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getCertificates().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link String } + * + * + */ + public List getCertificates() { + if (certificates == null) { + certificates = new ArrayList(); + } + return this.certificates; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/Token.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/Token.java new file mode 100644 index 000000000..8451e0344 --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/Token.java @@ -0,0 +1,97 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.datatype.XMLGregorianCalendar; + + +/** + *

Java class for token complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="token">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="expires" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
+ *         <element name="id" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "token", propOrder = { + "expires", + "id" +}) +public class Token { + + @XmlSchemaType(name = "dateTime") + protected XMLGregorianCalendar expires; + protected String id; + + /** + * Gets the value of the expires property. + * + * @return + * possible object is + * {@link XMLGregorianCalendar } + * + */ + public XMLGregorianCalendar getExpires() { + return expires; + } + + /** + * Sets the value of the expires property. + * + * @param value + * allowed object is + * {@link XMLGregorianCalendar } + * + */ + public void setExpires(XMLGregorianCalendar value) { + this.expires = value; + } + + /** + * Gets the value of the id property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getId() { + return id; + } + + /** + * Sets the value of the id property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setId(String value) { + this.id = value; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/User.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/User.java new file mode 100644 index 000000000..017e4092d --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/User.java @@ -0,0 +1,141 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for user complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="user">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="username" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *       <attribute name="enabled" use="required" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+ *       <attribute name="email" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "user", propOrder = { + "username" +}) +public class User { + + protected String username; + @XmlAttribute(name = "enabled", required = true) + protected boolean enabled; + @XmlAttribute(name = "email") + protected String email; + @XmlAttribute(name = "id") + protected String id; + + /** + * Gets the value of the username property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getUsername() { + return username; + } + + /** + * Sets the value of the username property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setUsername(String value) { + this.username = value; + } + + /** + * Gets the value of the enabled property. + * + */ + public boolean isEnabled() { + return enabled; + } + + /** + * Sets the value of the enabled property. + * + */ + public void setEnabled(boolean value) { + this.enabled = value; + } + + /** + * Gets the value of the email property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getEmail() { + return email; + } + + /** + * Sets the value of the email property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setEmail(String value) { + this.email = value; + } + + /** + * Gets the value of the id property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getId() { + return id; + } + + /** + * Sets the value of the id property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setId(String value) { + this.id = value; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/UserValidation.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/UserValidation.java new file mode 100644 index 000000000..f5f23aac0 --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/UserValidation.java @@ -0,0 +1,94 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for userValidation complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="userValidation">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="id" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "userValidation", propOrder = { + "id", + "name" +}) +public class UserValidation { + + protected String id; + protected String name; + + /** + * Gets the value of the id property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getId() { + return id; + } + + /** + * Sets the value of the id property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setId(String value) { + this.id = value; + } + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/ValidateAccess.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/ValidateAccess.java new file mode 100644 index 000000000..69c6bf369 --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/ValidateAccess.java @@ -0,0 +1,121 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for validateAccess complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="validateAccess">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="token" type="{http://platformlayer.org/auth/v1.0}token" minOccurs="0"/>
+ *         <element name="user" type="{http://platformlayer.org/auth/v1.0}userValidation" minOccurs="0"/>
+ *         <element name="project" type="{http://platformlayer.org/auth/v1.0}projectValidation" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "validateAccess", propOrder = { + "token", + "user", + "project" +}) +public class ValidateAccess { + + protected Token token; + protected UserValidation user; + protected ProjectValidation project; + + /** + * Gets the value of the token property. + * + * @return + * possible object is + * {@link Token } + * + */ + public Token getToken() { + return token; + } + + /** + * Sets the value of the token property. + * + * @param value + * allowed object is + * {@link Token } + * + */ + public void setToken(Token value) { + this.token = value; + } + + /** + * Gets the value of the user property. + * + * @return + * possible object is + * {@link UserValidation } + * + */ + public UserValidation getUser() { + return user; + } + + /** + * Sets the value of the user property. + * + * @param value + * allowed object is + * {@link UserValidation } + * + */ + public void setUser(UserValidation value) { + this.user = value; + } + + /** + * Gets the value of the project property. + * + * @return + * possible object is + * {@link ProjectValidation } + * + */ + public ProjectValidation getProject() { + return project; + } + + /** + * Sets the value of the project property. + * + * @param value + * allowed object is + * {@link ProjectValidation } + * + */ + public void setProject(ProjectValidation value) { + this.project = value; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/ValidateTokenResponse.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/ValidateTokenResponse.java new file mode 100644 index 000000000..29ecd4db9 --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/ValidateTokenResponse.java @@ -0,0 +1,67 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + + +package org.platformlayer.auth.v1; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for validateTokenResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="validateTokenResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="access" type="{http://platformlayer.org/auth/v1.0}validateAccess" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "validateTokenResponse", propOrder = { + "access" +}) +public class ValidateTokenResponse { + + protected ValidateAccess access; + + /** + * Gets the value of the access property. + * + * @return + * possible object is + * {@link ValidateAccess } + * + */ + public ValidateAccess getAccess() { + return access; + } + + /** + * Sets the value of the access property. + * + * @param value + * allowed object is + * {@link ValidateAccess } + * + */ + public void setAccess(ValidateAccess value) { + this.access = value; + } + +} diff --git a/auth/client/src/generated/xjc/org/platformlayer/auth/v1/package-info.java b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/package-info.java new file mode 100644 index 000000000..3bce1a7ff --- /dev/null +++ b/auth/client/src/generated/xjc/org/platformlayer/auth/v1/package-info.java @@ -0,0 +1,9 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2013.03.26 at 03:21:34 PM PDT +// + +@javax.xml.bind.annotation.XmlSchema(namespace = "http://platformlayer.org/auth/v1.0", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) +package org.platformlayer.auth.v1; diff --git a/auth/client/src/main/java/org/openstack/keystone/auth/client/Keystone.java b/auth/client/src/main/java/org/openstack/keystone/auth/client/Keystone.java deleted file mode 100644 index abd7cbc8c..000000000 --- a/auth/client/src/main/java/org/openstack/keystone/auth/client/Keystone.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.openstack.keystone.auth.client; - -public class Keystone { - public static final String AUTH_HEADER = "X-Auth-Token"; -} diff --git a/auth/client/src/main/java/org/openstack/keystone/auth/client/KeystoneAuthenticationClient.java b/auth/client/src/main/java/org/openstack/keystone/auth/client/KeystoneAuthenticationClient.java deleted file mode 100644 index a0c66cb9f..000000000 --- a/auth/client/src/main/java/org/openstack/keystone/auth/client/KeystoneAuthenticationClient.java +++ /dev/null @@ -1,129 +0,0 @@ -package org.openstack.keystone.auth.client; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Random; - -import javax.xml.bind.JAXBException; - -import org.openstack.docs.identity.api.v2.Auth; -import org.openstack.docs.identity.api.v2.AuthenticateRequest; -import org.openstack.docs.identity.api.v2.AuthenticateResponse; -import org.openstack.docs.identity.api.v2.PasswordCredentials; -import org.openstack.docs.identity.api.v2.TenantsList; -import org.openstack.utils.Utf8; -import org.platformlayer.CastUtils; -import org.platformlayer.IoUtils; -import org.platformlayer.WellKnownPorts; -import org.platformlayer.http.SimpleHttpRequest; -import org.platformlayer.http.SimpleHttpRequest.SimpleHttpResponse; -import org.platformlayer.xml.JaxbHelper; -import org.platformlayer.xml.UnmarshalException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class KeystoneAuthenticationClient { - static final Logger log = LoggerFactory.getLogger(KeystoneAuthenticationClient.class); - - final String authenticationUrl; - - public static final String DEFAULT_AUTHENTICATION_URL = "http://127.0.0.1:" - + WellKnownPorts.PORT_PLATFORMLAYER_AUTH_USER + "/v2.0/"; - - public static final Integer HTTP_500_ERROR = new Integer(500); - - protected static final int MAX_RETRIES = 10; - - static Random random = new Random(); - - public KeystoneAuthenticationClient(String authenticationUrl) { - this.authenticationUrl = authenticationUrl; - } - - public KeystoneAuthenticationClient() { - this(DEFAULT_AUTHENTICATION_URL); - } - - public TenantsList listTenants(KeystoneAuthenticationToken token) throws KeystoneAuthenticationException { - return doSimpleRequest(token, "GET", "tokens", null, TenantsList.class); - } - - public KeystoneAuthenticationToken authenticate(String tenantName, PasswordCredentials passwordCredentials) - throws KeystoneAuthenticationException { - Auth auth = new Auth(); - auth.setPasswordCredentials(passwordCredentials); - auth.setTenantName(tenantName); - - AuthenticateRequest request = new AuthenticateRequest(); - request.setAuth(auth); - - AuthenticateResponse response = doSimpleRequest(null, "POST", "tokens", request, AuthenticateResponse.class); - return new KeystoneAuthenticationToken(response.getAccess()); - } - - private T doSimpleRequest(KeystoneAuthenticationToken token, String method, String relativeUri, - Object postObject, Class responseClass) throws KeystoneAuthenticationException { - try { - URI uri = new URI(authenticationUrl + relativeUri); - - SimpleHttpRequest httpRequest = SimpleHttpRequest.build(method, uri); - - httpRequest.setRequestHeader("Accept", "application/xml"); - - if (token != null) { - token.populateRequest(httpRequest); - } - - if (postObject != null) { - httpRequest.setRequestHeader("Content-Type", "application/xml"); - String xml = serializeXml(postObject); - httpRequest.getOutputStream().write(Utf8.getBytes(xml)); - } - - SimpleHttpResponse response = httpRequest.doRequest(); - - int responseCode = response.getHttpResponseCode(); - switch (responseCode) { - case 401: - throw new KeystoneAuthenticationException("Platformlayer credentials were not correct"); - - case 200: - case 203: { - if (responseClass.equals(String.class)) { - return CastUtils.as(IoUtils.readAll(response.getInputStream()), responseClass); - } else { - return deserializeXml(response.getInputStream(), responseClass); - } - } - - default: - throw new KeystoneAuthenticationException("Unexpected result code: " + responseCode); - } - } catch (IOException e) { - throw new KeystoneAuthenticationException("Error communicating with authentication service", e); - } catch (URISyntaxException e) { - throw new KeystoneAuthenticationException("Error building authentication URI", e); - } - - } - - public static T deserializeXml(InputStream is, Class clazz) throws KeystoneAuthenticationException { - try { - return JaxbHelper.deserializeXmlObject(is, clazz, true); - } catch (UnmarshalException e) { - throw new KeystoneAuthenticationException("Error reading authentication response data", e); - } - } - - public static String serializeXml(Object object) throws KeystoneAuthenticationException { - try { - boolean formatted = false; - return JaxbHelper.toXml(object, formatted); - } catch (JAXBException e) { - throw new KeystoneAuthenticationException("Error serializing data", e); - } - } - -} diff --git a/auth/client/src/main/java/org/openstack/keystone/auth/client/KeystoneAuthenticationException.java b/auth/client/src/main/java/org/openstack/keystone/auth/client/KeystoneAuthenticationException.java deleted file mode 100644 index e7601b958..000000000 --- a/auth/client/src/main/java/org/openstack/keystone/auth/client/KeystoneAuthenticationException.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.openstack.keystone.auth.client; - -import org.platformlayer.auth.OpenstackAuthenticationException; - -public class KeystoneAuthenticationException extends OpenstackAuthenticationException { - private static final long serialVersionUID = 1L; - - public KeystoneAuthenticationException(String message) { - super(message); - } - - public KeystoneAuthenticationException(String message, Exception e) { - super(message, e); - } -} diff --git a/auth/client/src/main/java/org/openstack/keystone/auth/client/KeystoneAuthenticationToken.java b/auth/client/src/main/java/org/openstack/keystone/auth/client/KeystoneAuthenticationToken.java deleted file mode 100644 index b86e088f5..000000000 --- a/auth/client/src/main/java/org/openstack/keystone/auth/client/KeystoneAuthenticationToken.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.openstack.keystone.auth.client; - -import org.openstack.docs.identity.api.v2.Access; -import org.openstack.docs.identity.api.v2.Service; -import org.openstack.docs.identity.api.v2.ServiceEndpoint; -import org.platformlayer.auth.AuthenticationToken; -import org.platformlayer.http.SimpleHttpRequest; - -import com.google.common.base.Objects; - -public class KeystoneAuthenticationToken implements AuthenticationToken { - private final Access access; - - public KeystoneAuthenticationToken(Access access) { - this.access = access; - } - - public String getAuthTokenValue() { - return access.getToken().getId(); - } - - @Override - public String getServiceUrl(String serviceKey) { - for (Service service : access.getServiceCatalog()) { - if (Objects.equal(service.getType(), serviceKey)) { - String bestUrl = null; - for (ServiceEndpoint endpoint : service.getEndpoints()) { - bestUrl = endpoint.getPublicURL(); - if (bestUrl != null) { - break; - } - } - - if (bestUrl != null) { - return bestUrl; - } - } - } - return null; - } - - @Override - public void populateRequest(SimpleHttpRequest httpRequest) { - httpRequest.setRequestHeader("X-Auth-Token", getAuthTokenValue()); - } - -} \ No newline at end of file diff --git a/auth/client/src/main/java/org/openstack/keystone/auth/client/KeystoneAuthenticator.java b/auth/client/src/main/java/org/openstack/keystone/auth/client/KeystoneAuthenticator.java deleted file mode 100644 index 49c7515f4..000000000 --- a/auth/client/src/main/java/org/openstack/keystone/auth/client/KeystoneAuthenticator.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.openstack.keystone.auth.client; - -import java.net.MalformedURLException; -import java.net.URL; - -import org.openstack.docs.identity.api.v2.PasswordCredentials; -import org.platformlayer.auth.AuthenticationToken; -import org.platformlayer.auth.Authenticator; - -public class KeystoneAuthenticator implements Authenticator { - final String tenantId; - - final String username; - final String password; - - final KeystoneAuthenticationClient client; - - AuthenticationToken token = null; - - public KeystoneAuthenticator(String tenantId, String username, String password, String server) { - this.tenantId = tenantId; - this.username = username; - this.password = password; - String authenticationUrl = server != null ? server : KeystoneAuthenticationClient.DEFAULT_AUTHENTICATION_URL; - - this.client = new KeystoneAuthenticationClient(authenticationUrl); - } - - @Override - public AuthenticationToken getAuthenticationToken() throws KeystoneAuthenticationException { - if (token == null) { - PasswordCredentials passwordCredentials = new PasswordCredentials(); - passwordCredentials.setUsername(username); - passwordCredentials.setPassword(password); - - token = client.authenticate(tenantId, passwordCredentials); - } - return token; - } - - @Override - public void clearAuthenticationToken() { - token = null; - } - - @Override - public String getHost() { - try { - URL url = new URL(client.authenticationUrl); - return url.getHost(); - } catch (MalformedURLException e) { - throw new IllegalStateException("Error parsing URL", e); - } - } - -} diff --git a/auth/client/src/main/java/org/openstack/keystone/service/AccountId.java b/auth/client/src/main/java/org/openstack/keystone/service/AccountId.java deleted file mode 100644 index 53a7a303c..000000000 --- a/auth/client/src/main/java/org/openstack/keystone/service/AccountId.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.openstack.keystone.service; - -import org.platformlayer.model.StringWrapper; - -public class AccountId extends StringWrapper { - public AccountId(String id) { - super(id); - } - -} diff --git a/auth/client/src/main/java/org/openstack/keystone/service/AuthenticationTokenValidator.java b/auth/client/src/main/java/org/openstack/keystone/service/AuthenticationTokenValidator.java deleted file mode 100644 index 00b54fdc3..000000000 --- a/auth/client/src/main/java/org/openstack/keystone/service/AuthenticationTokenValidator.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.openstack.keystone.service; - -import org.platformlayer.model.Authentication; - -public interface AuthenticationTokenValidator { - Authentication validate(String authToken); -} diff --git a/auth/client/src/main/java/org/openstack/keystone/service/AuthenticationTokenValidatorFilter.java b/auth/client/src/main/java/org/openstack/keystone/service/AuthenticationTokenValidatorFilter.java deleted file mode 100644 index da9dda21e..000000000 --- a/auth/client/src/main/java/org/openstack/keystone/service/AuthenticationTokenValidatorFilter.java +++ /dev/null @@ -1,10 +0,0 @@ -//package org.openstack.keystone.service; -// -//import javax.inject.Inject; -// -//public class AuthenticationTokenValidatorFilter extends OpenstackAuthenticationFilterBase { -// @Inject -// public AuthenticationTokenValidatorFilter(AuthenticationTokenValidator keystoneTokenValidator) { -// super(keystoneTokenValidator); -// } -// } diff --git a/auth/client/src/main/java/org/openstack/keystone/service/DevelopmentOpenstackAuthenticationFilter.java b/auth/client/src/main/java/org/openstack/keystone/service/DevelopmentOpenstackAuthenticationFilter.java deleted file mode 100644 index c3b4a440a..000000000 --- a/auth/client/src/main/java/org/openstack/keystone/service/DevelopmentOpenstackAuthenticationFilter.java +++ /dev/null @@ -1,33 +0,0 @@ -//package org.openstack.keystone.service; -// -//import org.platformlayer.ApplicationMode; -//import org.platformlayer.model.Authentication; -// -//public class DevelopmentOpenstackAuthenticationFilter extends OpenstackAuthenticationFilterBase { -// public DevelopmentOpenstackAuthenticationFilter() { -// super(new DevelopmentAuthTokenValidator()); -// -// ApplicationMode.onlyForDevelopment(); -// } -// -// public static final String PREFIX = "DEV-TOKEN-"; -// -// static class DevelopmentAuthTokenValidator implements AuthenticationTokenValidator { -// public DevelopmentAuthTokenValidator() { -// } -// -// @Override -// public Authentication validate(String authToken) { -// AccountId accountId = null; -// -// authToken = authToken.trim(); -// -// if (authToken.startsWith(PREFIX)) { -// String accountIdString = authToken.substring(PREFIX.length()); -// accountId = new AccountId(accountIdString); -// } -// -// return accountId; -// } -// } -// } diff --git a/auth/client/src/main/java/org/openstack/keystone/service/DevelopmentTokenValidator.java b/auth/client/src/main/java/org/openstack/keystone/service/DevelopmentTokenValidator.java deleted file mode 100644 index 428c5e3c1..000000000 --- a/auth/client/src/main/java/org/openstack/keystone/service/DevelopmentTokenValidator.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.openstack.keystone.service; - -import javax.inject.Inject; - -import org.platformlayer.ApplicationMode; -import org.platformlayer.model.Authentication; -import org.platformlayer.model.RoleId; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DevelopmentTokenValidator implements AuthenticationTokenValidator { - static final Logger log = LoggerFactory.getLogger(DevelopmentTokenValidator.class); - - @Inject - KeystoneTokenValidator keystone; - - public DevelopmentTokenValidator() { - if (!ApplicationMode.isDevelopment()) { - throw new IllegalStateException(); - } - } - - public static final String PREFIX = "DEV-TOKEN-"; - - class DevelopmentAuthentication implements Authentication { - - final String project; - final String userKey; - - public DevelopmentAuthentication(String userKey, String project) { - super(); - this.userKey = userKey; - this.project = project; - } - - @Override - public String getProject() { - return project; - } - - @Override - public boolean isInRole(String project, RoleId role) { - return true; - } - - @Override - public byte[] getUserSecret() { - return null; - } - - @Override - public String getUserKey() { - return userKey; - } - - } - - @Override - public Authentication validate(String authToken) { - authToken = authToken.trim(); - - if (authToken.startsWith(PREFIX)) { - String project = authToken.substring(PREFIX.length()); - String userKey = project; - - return new DevelopmentAuthentication(userKey, project); - } - - return keystone.validate(authToken); - } -} diff --git a/auth/client/src/main/java/org/openstack/keystone/service/KeystoneAuthentication.java b/auth/client/src/main/java/org/openstack/keystone/service/KeystoneAuthentication.java deleted file mode 100644 index abcb9602d..000000000 --- a/auth/client/src/main/java/org/openstack/keystone/service/KeystoneAuthentication.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.openstack.keystone.service; - -import java.util.List; - -import org.platformlayer.model.Authentication; -import org.platformlayer.model.RoleId; - -public class KeystoneAuthentication implements Authentication { - private final String userKey; - private final String tenantKey; - private final List roles; - private final byte[] userSecret; - - public KeystoneAuthentication(String userKey, String tenantKey, byte[] userSecret, List roles) { - this.userKey = userKey; - this.tenantKey = tenantKey; - this.userSecret = userSecret; - this.roles = roles; - } - - @Override - public String getProject() { - return tenantKey; - } - - @Override - public boolean isInRole(String project, RoleId role) { - if (project.equals(tenantKey)) { - return roles.contains(role.getKey()); - } - return false; - } - - @Override - public byte[] getUserSecret() { - return userSecret; - } - - @Override - public String getUserKey() { - return userKey; - } -} diff --git a/auth/client/src/main/java/org/openstack/keystone/service/KeystoneTokenValidator.java b/auth/client/src/main/java/org/openstack/keystone/service/KeystoneTokenValidator.java deleted file mode 100644 index fd1910875..000000000 --- a/auth/client/src/main/java/org/openstack/keystone/service/KeystoneTokenValidator.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.openstack.keystone.service; - -import java.util.List; - -import org.openstack.docs.identity.api.v2.Role; -import org.openstack.docs.identity.api.v2.Tenant; -import org.openstack.docs.identity.api.v2.UserValidation; -import org.openstack.docs.identity.api.v2.ValidateAccess; -import org.openstack.docs.identity.api.v2.ValidateTokenResponse; -import org.openstack.keystone.auth.client.Keystone; -import org.platformlayer.PlatformLayerClientException; -import org.platformlayer.WellKnownPorts; -import org.platformlayer.http.SimpleHttpRequest; -import org.platformlayer.model.Authentication; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.Lists; - -public class KeystoneTokenValidator extends RestfulClient implements AuthenticationTokenValidator { - static final Logger log = LoggerFactory.getLogger(KeystoneTokenValidator.class); - - public static final String DEFAULT_AUTHENTICATION_URL = "http://127.0.0.1:" - + WellKnownPorts.PORT_PLATFORMLAYER_AUTH_ADMIN + "/"; - - final String authenticationToken; - - public KeystoneTokenValidator(String baseUrl, String authenticationToken) { - super(baseUrl); - this.authenticationToken = authenticationToken; - } - - @Override - protected void addHeaders(SimpleHttpRequest httpRequest) { - httpRequest.setRequestHeader(Keystone.AUTH_HEADER, authenticationToken); - } - - // public KeystoneAuthenticationToken authenticate(String tenantName, PasswordCredentials passwordCredentials) - // throws KeystoneAuthenticationException { - // Auth auth = new Auth(); - // auth.setPasswordCredentials(passwordCredentials); - // auth.setTenantName(tenantName); - // - // AuthenticateRequest request = new AuthenticateRequest(); - // request.setAuth(auth); - // - // AuthenticateResponse response = doSimpleRequest("POST", "tokens", request, AuthenticateResponse.class); - // return new KeystoneAuthenticationToken(response.getAccess()); - // } - - @Override - public Authentication validate(String authToken) { - // v2.0/tokens/{userToken}[?belongsTo={tenant}] - - authToken = authToken.trim(); - - String url = "v2.0/tokens/" + authToken; - - try { - ValidateTokenResponse response = doSimpleRequest("GET", url, null, ValidateTokenResponse.class); - - ValidateAccess access = response.getAccess(); - - Tenant tenant = access.getToken().getTenant(); - String tenantId = tenant.getId(); - if (tenantId == null) { - return null; - } - - List roles = Lists.newArrayList(); - UserValidation userInfo = access.getUser(); - for (Role role : userInfo.getRoles()) { - if (!role.getTenantId().equals(tenantId)) { - throw new IllegalStateException("Tenant mismatch: " + role.getTenantId() + " vs " + tenantId); - } - roles.add(role.getName()); - } - - byte[] userSecret = userInfo.getSecret(); - String userKey = userInfo.getName(); - - KeystoneAuthentication auth = new KeystoneAuthentication(userKey, tenantId, userSecret, roles); - return auth; - } catch (PlatformLayerClientException e) { - if (e.getHttpResponseCode() != null && e.getHttpResponseCode() == 404) { - // Not found => invalid token - return null; - } - throw new IllegalArgumentException("Error while validating token", e); - } - } -} diff --git a/auth/client/src/main/java/org/openstack/keystone/service/OpenstackAuthenticationFilterBase.java b/auth/client/src/main/java/org/openstack/keystone/service/OpenstackAuthenticationFilterBase.java deleted file mode 100644 index 9b2547d66..000000000 --- a/auth/client/src/main/java/org/openstack/keystone/service/OpenstackAuthenticationFilterBase.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.openstack.keystone.service; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.log4j.Logger; -import org.platformlayer.Scope; -import org.platformlayer.model.Authentication; - -public abstract class OpenstackAuthenticationFilterBase implements Filter { - static final Logger log = Logger.getLogger(OpenstackAuthenticationFilterBase.class); - - private final AuthenticationTokenValidator authenticationTokenValidator; - - protected OpenstackAuthenticationFilterBase(AuthenticationTokenValidator authenticationTokenValidator) { - this.authenticationTokenValidator = authenticationTokenValidator; - } - - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) - throws IOException, ServletException { - Scope authenticatedScope = Scope.inherit(); - - // Fail safe - authenticatedScope.put(Authentication.class, null); - - if (servletRequest instanceof HttpServletRequest) { - HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; - HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse; - - try { - Authentication authenticated = attemptAuthentication(httpServletRequest); - - if (authenticated == null) { - httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - return; - } else { - populateScope(authenticatedScope, authenticated); - } - } catch (SecurityException e) { - httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - return; - } catch (Exception e) { - // If we're down, don't tell the user that their password is wrong - log.warn("Unexpected error in authentication filter", e); - httpServletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - return; - } - } - - authenticatedScope.push(); - try { - filterChain.doFilter(servletRequest, servletResponse); - } finally { - authenticatedScope.pop(); - } - } - - protected Authentication attemptAuthentication(HttpServletRequest httpServletRequest) throws Exception { - String authToken = httpServletRequest.getHeader("X-Auth-Token"); - - Authentication authenticated = null; - - if (authToken != null) { - authenticated = authenticationTokenValidator.validate(authToken); - } - - return authenticated; - } - - protected void populateScope(Scope authenticatedScope, Authentication authenticated) throws Exception { - authenticatedScope.put(Authentication.class, authenticated); - } - - @Override - public void destroy() { - - } - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - - } - -} diff --git a/auth/client/src/main/java/org/openstack/keystone/service/RestfulClient.java b/auth/client/src/main/java/org/openstack/keystone/service/RestfulClient.java deleted file mode 100644 index e3fc9a763..000000000 --- a/auth/client/src/main/java/org/openstack/keystone/service/RestfulClient.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.openstack.keystone.service; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; - -import javax.xml.bind.JAXBException; - -import org.apache.log4j.Logger; -import org.openstack.keystone.auth.client.KeystoneAuthenticationException; -import org.openstack.utils.Utf8; -import org.platformlayer.CastUtils; -import org.platformlayer.IoUtils; -import org.platformlayer.PlatformLayerClientException; -import org.platformlayer.http.SimpleHttpRequest; -import org.platformlayer.http.SimpleHttpRequest.SimpleHttpResponse; -import org.platformlayer.xml.JaxbHelper; -import org.platformlayer.xml.UnmarshalException; - -public class RestfulClient { - static final Logger log = Logger.getLogger(RestfulClient.class); - - final String baseUrl; - - public RestfulClient(String baseUrl) { - this.baseUrl = baseUrl; - } - - protected T doSimpleRequest(String method, String relativeUri, Object postObject, Class responseClass) - throws PlatformLayerClientException { - try { - URI uri = new URI(baseUrl + relativeUri); - - log.info("HTTP Request: " + method + " " + uri); - - SimpleHttpRequest httpRequest = SimpleHttpRequest.build(method, uri); - httpRequest.setRequestHeader("Accept", "application/xml"); - - addHeaders(httpRequest); - - if (postObject != null) { - httpRequest.setRequestHeader("Content-Type", "application/xml"); - String xml = serializeXml(postObject); - httpRequest.getOutputStream().write(Utf8.getBytes(xml)); - } - - SimpleHttpResponse response = httpRequest.doRequest(); - - int responseCode = response.getHttpResponseCode(); - switch (responseCode) { - case 401: - throw new KeystoneAuthenticationException("Authentication failure"); - - case 200: - case 203: { - if (responseClass.equals(String.class)) { - return CastUtils.as(IoUtils.readAll(response.getInputStream()), responseClass); - } else { - return deserializeXml(response.getInputStream(), responseClass); - } - } - - default: - throw new PlatformLayerClientException("Unexpected result code: " + responseCode, null, responseCode); - } - } catch (IOException e) { - throw new KeystoneAuthenticationException("Error communicating with service", e); - } catch (URISyntaxException e) { - throw new KeystoneAuthenticationException("Error building URI", e); - } - - } - - protected void addHeaders(SimpleHttpRequest httpRequest) { - - } - - T deserializeXml(InputStream is, Class clazz) throws KeystoneAuthenticationException { - try { - return JaxbHelper.deserializeXmlObject(is, clazz, true); - } catch (UnmarshalException e) { - throw new KeystoneAuthenticationException("Error reading authentication response data", e); - } - } - - String serializeXml(Object object) throws KeystoneAuthenticationException { - try { - boolean formatted = false; - return JaxbHelper.toXml(object, formatted); - } catch (JAXBException e) { - throw new KeystoneAuthenticationException("Error serializing data", e); - } - } -} diff --git a/auth/client/src/main/java/org/platformlayer/auth/AuthenticationToken.java b/auth/client/src/main/java/org/platformlayer/auth/AuthenticationToken.java deleted file mode 100644 index 0496bf2c4..000000000 --- a/auth/client/src/main/java/org/platformlayer/auth/AuthenticationToken.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.platformlayer.auth; - -import org.platformlayer.http.SimpleHttpRequest; - -public interface AuthenticationToken { - String getServiceUrl(String serviceKey); - - void populateRequest(SimpleHttpRequest httpRequest); -} diff --git a/auth/client/src/main/java/org/platformlayer/auth/Authenticator.java b/auth/client/src/main/java/org/platformlayer/auth/Authenticator.java index af5d52b78..0beb2bb60 100644 --- a/auth/client/src/main/java/org/platformlayer/auth/Authenticator.java +++ b/auth/client/src/main/java/org/platformlayer/auth/Authenticator.java @@ -1,9 +1,14 @@ package org.platformlayer.auth; +import java.io.PrintStream; + + public interface Authenticator { - AuthenticationToken getAuthenticationToken() throws OpenstackAuthenticationException; + AuthenticationToken getAuthenticationToken() throws PlatformlayerAuthenticationClientException; void clearAuthenticationToken(); String getHost(); + + void setDebug(PrintStream debug); } diff --git a/auth/client/src/main/java/org/platformlayer/auth/OpenstackAuthenticationException.java b/auth/client/src/main/java/org/platformlayer/auth/OpenstackAuthenticationException.java deleted file mode 100644 index 8edc412f9..000000000 --- a/auth/client/src/main/java/org/platformlayer/auth/OpenstackAuthenticationException.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.platformlayer.auth; - -import org.platformlayer.PlatformLayerClientException; - -public class OpenstackAuthenticationException extends PlatformLayerClientException { - private static final long serialVersionUID = 1L; - - public OpenstackAuthenticationException(String message) { - super(message); - } - - public OpenstackAuthenticationException(String message, Exception e) { - super(message, e); - } -} diff --git a/auth/client/src/main/java/org/platformlayer/auth/PlatformlayerAuthenticationClientException.java b/auth/client/src/main/java/org/platformlayer/auth/PlatformlayerAuthenticationClientException.java new file mode 100644 index 000000000..c03925196 --- /dev/null +++ b/auth/client/src/main/java/org/platformlayer/auth/PlatformlayerAuthenticationClientException.java @@ -0,0 +1,13 @@ +package org.platformlayer.auth; + +public class PlatformlayerAuthenticationClientException extends Exception { + private static final long serialVersionUID = 1L; + + public PlatformlayerAuthenticationClientException(String message) { + super(message); + } + + public PlatformlayerAuthenticationClientException(String message, Exception e) { + super(message, e); + } +} diff --git a/auth/client/src/main/java/org/platformlayer/auth/PlatformlayerAuthenticationToken.java b/auth/client/src/main/java/org/platformlayer/auth/PlatformlayerAuthenticationToken.java new file mode 100644 index 000000000..008e5c393 --- /dev/null +++ b/auth/client/src/main/java/org/platformlayer/auth/PlatformlayerAuthenticationToken.java @@ -0,0 +1,76 @@ +package org.platformlayer.auth; + +import org.platformlayer.auth.v1.Access; +import org.platformlayer.http.HttpRequest; + +public class PlatformlayerAuthenticationToken implements AuthenticationToken { + private final String authToken; + + public PlatformlayerAuthenticationToken(String authToken) { + this.authToken = authToken; + } + + public PlatformlayerAuthenticationToken(Access access) { + this.authToken = access.getToken().getId(); + } + + public String getAuthTokenValue() { + return authToken; + } + + // @Override + // public String getServiceUrl(String serviceKey) { + // // for (Service service : access.getServiceCatalog()) { + // // if (Objects.equal(service.getType(), serviceKey)) { + // // String bestUrl = null; + // // for (ServiceEndpoint endpoint : service.getEndpoints()) { + // // bestUrl = endpoint.getPublicURL(); + // // if (bestUrl != null) { + // // break; + // // } + // // } + // // + // // if (bestUrl != null) { + // // return bestUrl; + // // } + // // } + // // } + // return null; + // } + + @Override + public void populateRequest(HttpRequest httpRequest) { + httpRequest.setRequestHeader("X-Auth-Token", getAuthTokenValue()); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((authToken == null) ? 0 : authToken.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + PlatformlayerAuthenticationToken other = (PlatformlayerAuthenticationToken) obj; + if (authToken == null) { + if (other.authToken != null) { + return false; + } + } else if (!authToken.equals(other.authToken)) { + return false; + } + return true; + } + +} \ No newline at end of file diff --git a/auth/client/src/main/java/org/platformlayer/auth/PlatformlayerInvalidCredentialsException.java b/auth/client/src/main/java/org/platformlayer/auth/PlatformlayerInvalidCredentialsException.java new file mode 100644 index 000000000..14010efb3 --- /dev/null +++ b/auth/client/src/main/java/org/platformlayer/auth/PlatformlayerInvalidCredentialsException.java @@ -0,0 +1,11 @@ +package org.platformlayer.auth; + + +public class PlatformlayerInvalidCredentialsException extends PlatformlayerAuthenticationClientException { + private static final long serialVersionUID = 1L; + + public PlatformlayerInvalidCredentialsException(String message) { + super(message); + } + +} diff --git a/auth/client/src/main/java/org/platformlayer/auth/test/OpenstackAuthenticationClient.java b/auth/client/src/main/java/org/platformlayer/auth/test/OpenstackAuthenticationClient.java deleted file mode 100644 index 2ce9782ed..000000000 --- a/auth/client/src/main/java/org/platformlayer/auth/test/OpenstackAuthenticationClient.java +++ /dev/null @@ -1,124 +0,0 @@ -package org.platformlayer.auth.test; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Map; -import java.util.Random; - -import org.platformlayer.auth.OpenstackAuthenticationException; -import org.platformlayer.http.SimpleHttpRequest; -import org.platformlayer.http.SimpleHttpRequest.SimpleHttpResponse; -import org.platformlayer.xml.JaxbHelper; -import org.platformlayer.xml.UnmarshalException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class OpenstackAuthenticationClient { - static final Logger log = LoggerFactory.getLogger(OpenstackAuthenticationClient.class); - - final String username; - final private String secret; - - OpenstackAuthenticationToken authenticationToken; - - private String authenticationUrl = URL_AUTHENTICATE; - - static final String URL_AUTHENTICATE = "https://auth.api.rackspacecloud.com/v1.0"; - - public static final Integer HTTP_500_ERROR = new Integer(500); - - protected static final int MAX_RETRIES = 10; - - static Random random = new Random(); - - public OpenstackAuthenticationClient(String username, String secret) { - this.username = username; - this.secret = secret; - } - - public synchronized OpenstackAuthenticationToken getAuthenticationToken() throws OpenstackAuthenticationException { - if (authenticationToken == null) { - authenticationToken = authenticate(); - } - - return authenticationToken; - } - - private OpenstackAuthenticationToken authenticate() throws OpenstackAuthenticationException { - if (username == null || secret == null) { - throw new OpenstackAuthenticationException("Username and secret are both required"); - } - - try { - // GET /v1.0 HTTP/1.1 - // Host: auth.api.rackspacecloud.com - // X-Auth-User: jdoe - // X-Auth-Key: a86850deb2742ec3cb41518e26aa2d89 - URI uri = new URI(authenticationUrl); - - SimpleHttpRequest httpRequest = SimpleHttpRequest.build("GET", uri); - httpRequest.setRequestHeader("X-Auth-User", this.username); - httpRequest.setRequestHeader("X-Auth-Key", this.secret); - - SimpleHttpResponse response = httpRequest.doRequest(); - - int responseCode = response.getHttpResponseCode(); - switch (responseCode) { - case 401: - throw new OpenstackAuthenticationException("Openstack credentials were not correct"); - - case 204: - /* - * If authentication is successful, an HTTP status 204 No Content is returned with three cloud service - * headers, X-Server-Management-Url, X-Storage-Url, X-CDN-Management-Url, as well as X-Auth-Token - */ - - String authToken = getRequiredHeader(response, "X-Auth-Token"); - - Map allHeaders = response.getHeadersRemoveDuplicates(); - - return new OpenstackAuthenticationToken(authToken, allHeaders); - - default: - throw new OpenstackAuthenticationException("Unexpected return code from Rackspace Cloud during login: " - + responseCode); - } - } catch (IOException e) { - throw new OpenstackAuthenticationException("Error communicating with authentication service", e); - } catch (URISyntaxException e) { - throw new OpenstackAuthenticationException("Error building rackspace URI", e); - } - } - - private static String getRequiredHeader(SimpleHttpResponse response, String headerName) - throws OpenstackAuthenticationException { - String headerValue = response.getResponseHeaderField(headerName); - if (headerValue == null) { - throw new OpenstackAuthenticationException("Did not find required header: " + headerName); - } - return headerValue; - } - - public static T deserializeXml(InputStream is, Class clazz) throws OpenstackAuthenticationException { - try { - return JaxbHelper.deserializeXmlObject(is, clazz, true); - } catch (UnmarshalException e) { - throw new OpenstackAuthenticationException("Error reading authentication response data", e); - } - } - - public String getAuthenticationUrl() { - return authenticationUrl; - } - - public void setAuthenticationUrl(String authenticationUrl) { - this.authenticationUrl = authenticationUrl; - } - - public OpenstackAuthenticationToken reauthenticate() throws OpenstackAuthenticationException { - this.authenticationToken = null; - return getAuthenticationToken(); - } -} diff --git a/auth/client/src/main/java/org/platformlayer/auth/test/OpenstackAuthenticationToken.java b/auth/client/src/main/java/org/platformlayer/auth/test/OpenstackAuthenticationToken.java deleted file mode 100644 index 2c9e5556d..000000000 --- a/auth/client/src/main/java/org/platformlayer/auth/test/OpenstackAuthenticationToken.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.platformlayer.auth.test; - -import java.util.Map; - -public class OpenstackAuthenticationToken { - private final String authToken; - private final Map allHeaders; - - public OpenstackAuthenticationToken(String authToken, Map allHeaders) { - this.authToken = authToken; - this.allHeaders = allHeaders; - } - - public String getHeaderValue(String key) { - return allHeaders.get(key); - } - - public String getAuthTokenValue() { - return authToken; - } - -} \ No newline at end of file diff --git a/auth/client/src/main/schemas/keystone.xsd b/auth/client/src/main/schemas/keystone.xsd index d749e0e31..bdcbe4faf 100644 --- a/auth/client/src/main/schemas/keystone.xsd +++ b/auth/client/src/main/schemas/keystone.xsd @@ -1,5 +1,5 @@ - + @@ -9,15 +9,21 @@ - + - + + + + + + + - + - + @@ -25,10 +31,17 @@ - + + + + + + + - + + @@ -36,158 +49,141 @@ - - + - + + - - - - + - + - + + - + - - - - - + - - - - - - - - + - - - - + - - + - - + - + - - - - + + + - + - - - + - + - + + - + - + - + - + - + - - - - - - + + + + - - - + - + + + - + - + + - - - - + + + + - + - + + + + - + - + + - + - + + + - - - - + - - + + - + - + + diff --git a/auth/conf.db/system.conf b/auth/conf.db/system.conf index 174d63001..fc1a9ea65 100644 --- a/auth/conf.db/system.conf +++ b/auth/conf.db/system.conf @@ -7,3 +7,12 @@ auth.jdbc.username=platformlayer_ops auth.jdbc.password=platformlayer-password sharedsecret=SHAREDSECRET + +keystore=/home/justinsb/.credentials/ssl/dev.jks + +metrics.report.ssl.cert=clientcert.systemauth +metrics.report.url=https://127.0.0.1:8099/ +metrics.report.project=platformlayer + +metrics.report.ssl.keys=7b0ccb3d377f815496fce615ce6b4c09 + diff --git a/auth/conf.db/user.conf b/auth/conf.db/user.conf index 96dff3660..bf155532d 100644 --- a/auth/conf.db/user.conf +++ b/auth/conf.db/user.conf @@ -7,3 +7,13 @@ auth.jdbc.password=platformlayer-password sharedsecret=SHAREDSECRET + +keystore=/home/justinsb/.credentials/ssl/dev.jks + + +metrics.report.ssl.cert=clientcert.systemauth +metrics.report.url=https://127.0.0.1:8099/ +metrics.report.project=platformlayer + +metrics.report.ssl.keys=7b0ccb3d377f815496fce615ce6b4c09 + diff --git a/auth/keystone-api/pom.xml b/auth/keystone-api/pom.xml deleted file mode 100644 index 468ffbdd1..000000000 --- a/auth/keystone-api/pom.xml +++ /dev/null @@ -1,20 +0,0 @@ - - 4.0.0 - - - org.platformlayer - keystone-parent - 1.0-SNAPSHOT - - - keystone-api - Keystone :: API - - - - org.platformlayer - model-shared - - - diff --git a/auth/keystone-api/src/main/java/org/openstack/keystone/services/AuthenticationInfo.java b/auth/keystone-api/src/main/java/org/openstack/keystone/services/AuthenticationInfo.java deleted file mode 100644 index 619aabdbb..000000000 --- a/auth/keystone-api/src/main/java/org/openstack/keystone/services/AuthenticationInfo.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.openstack.keystone.services; - -public class AuthenticationInfo { - final String userId; - final byte[] tokenSecret; - - public AuthenticationInfo(String userId, byte[] tokenSecret) { - this.userId = userId; - this.tokenSecret = tokenSecret; - } - - public String getUserId() { - return userId; - } - - public byte[] getTokenSecret() { - return tokenSecret; - } -} diff --git a/auth/keystone-api/src/main/java/org/openstack/keystone/services/GenericAuthenticator.java b/auth/keystone-api/src/main/java/org/openstack/keystone/services/GenericAuthenticator.java deleted file mode 100644 index c723dee23..000000000 --- a/auth/keystone-api/src/main/java/org/openstack/keystone/services/GenericAuthenticator.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.openstack.keystone.services; - -public interface GenericAuthenticator { - AuthenticationInfo authenticate(String username, String password) throws AuthenticatorException; - - GroupMembershipOracle getGroupMembership(); - - byte[] getUserSecret(String userId, byte[] tokenSecret) throws AuthenticatorException; -} diff --git a/auth/keystone-api/src/main/java/org/openstack/keystone/services/GroupMembershipOracle.java b/auth/keystone-api/src/main/java/org/openstack/keystone/services/GroupMembershipOracle.java deleted file mode 100644 index 61df56a17..000000000 --- a/auth/keystone-api/src/main/java/org/openstack/keystone/services/GroupMembershipOracle.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.openstack.keystone.services; - -import java.util.List; - -public interface GroupMembershipOracle { - List getGroups(String key, boolean isGroup) throws AuthenticatorException; -} diff --git a/auth/keystone-api/src/main/java/org/openstack/keystone/services/SystemAuthenticator.java b/auth/keystone-api/src/main/java/org/openstack/keystone/services/SystemAuthenticator.java deleted file mode 100644 index 4df741e27..000000000 --- a/auth/keystone-api/src/main/java/org/openstack/keystone/services/SystemAuthenticator.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.openstack.keystone.services; - -public interface SystemAuthenticator extends GenericAuthenticator { - -} diff --git a/auth/keystone-api/src/main/java/org/openstack/keystone/services/SystemAuthenticatorAdaptor.java b/auth/keystone-api/src/main/java/org/openstack/keystone/services/SystemAuthenticatorAdaptor.java deleted file mode 100644 index 92e759387..000000000 --- a/auth/keystone-api/src/main/java/org/openstack/keystone/services/SystemAuthenticatorAdaptor.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.openstack.keystone.services; - -public class SystemAuthenticatorAdaptor implements SystemAuthenticator { - final GenericAuthenticator authenticator; - - public SystemAuthenticatorAdaptor(GenericAuthenticator authenticator) { - this.authenticator = authenticator; - } - - @Override - public AuthenticationInfo authenticate(String username, String password) throws AuthenticatorException { - return authenticator.authenticate(username, password); - } - - @Override - public GroupMembershipOracle getGroupMembership() { - return authenticator.getGroupMembership(); - } - - @Override - public byte[] getUserSecret(String userId, byte[] tokenSecret) throws AuthenticatorException { - return authenticator.getUserSecret(userId, tokenSecret); - } -} \ No newline at end of file diff --git a/auth/keystone-api/src/main/java/org/openstack/keystone/services/UserAuthenticator.java b/auth/keystone-api/src/main/java/org/openstack/keystone/services/UserAuthenticator.java deleted file mode 100644 index 2e7b09637..000000000 --- a/auth/keystone-api/src/main/java/org/openstack/keystone/services/UserAuthenticator.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.openstack.keystone.services; - -public interface UserAuthenticator extends GenericAuthenticator { -} diff --git a/auth/keystone-api/src/main/java/org/openstack/keystone/services/UserAuthenticatorAdaptor.java b/auth/keystone-api/src/main/java/org/openstack/keystone/services/UserAuthenticatorAdaptor.java deleted file mode 100644 index 08a76b81c..000000000 --- a/auth/keystone-api/src/main/java/org/openstack/keystone/services/UserAuthenticatorAdaptor.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.openstack.keystone.services; - -public class UserAuthenticatorAdaptor implements UserAuthenticator { - final GenericAuthenticator authenticator; - - public UserAuthenticatorAdaptor(GenericAuthenticator authenticator) { - this.authenticator = authenticator; - } - - @Override - public AuthenticationInfo authenticate(String username, String password) throws AuthenticatorException { - return authenticator.authenticate(username, password); - } - - @Override - public GroupMembershipOracle getGroupMembership() { - return authenticator.getGroupMembership(); - } - - @Override - public byte[] getUserSecret(String userId, byte[] tokenSecret) throws AuthenticatorException { - return authenticator.getUserSecret(userId, tokenSecret); - } -} \ No newline at end of file diff --git a/auth/keystone-cli/pom.xml b/auth/keystone-cli/pom.xml index 2b3497a13..284db0e36 100644 --- a/auth/keystone-cli/pom.xml +++ b/auth/keystone-cli/pom.xml @@ -1,44 +1,87 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + 4.0.0 - - org.platformlayer - keystone-parent - 1.0-SNAPSHOT - + + org.platformlayer + keystone-parent + 1.0-SNAPSHOT + - keystone-cli - Keystone :: CLI + keystone-cli + Keystone :: CLI - - - org.platformlayer - keystone-api - - - - org.platformlayer - shared-cli - + + + com.fathomdb + fathomdb-cli + - - org.platformlayer - platformlayer-auth - - - postgresql - postgresql - + + org.platformlayer + platformlayer-auth + + + postgresql + postgresql + - - org.slf4j - slf4j-log4j12 - - - - + + ch.qos.logback + logback-classic + + + + com.google.inject + guice + + + + com.fathomdb + fathomdb-http + + + + com.fathomdb + fathomdb-metrics + 1.0-SNAPSHOT + + + + + postgresql + postgresql + + + + + org.apache.tomcat + tomcat-jdbc + + + + + + eu.somatik.serviceloader-maven-plugin + serviceloader-maven-plugin + 1.0.2 + + + com.fathomdb.cli.commands.CommandRunner + com.fathomdb.cli.formatter.Formatter + + + + + + generate + + + + + + org.apache.maven.plugins maven-shade-plugin diff --git a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/KeystoneCliContext.java b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/KeystoneCliContext.java index 48496520f..698374989 100644 --- a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/KeystoneCliContext.java +++ b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/KeystoneCliContext.java @@ -1,17 +1,36 @@ package org.platformlayer.keystone.cli; +import java.io.File; +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.util.List; +import java.util.Properties; + import org.platformlayer.RepositoryException; -import org.platformlayer.auth.OpsUser; -import org.platformlayer.auth.UserRepository; +import org.platformlayer.auth.KeystoneJdbcModule; +import org.platformlayer.auth.UserDatabase; +import org.platformlayer.auth.UserEntity; +import org.platformlayer.config.ConfigurationModule; +import org.platformlayer.crypto.CertificateReader; import org.platformlayer.keystone.cli.commands.KeystoneCommandRegistry; import org.platformlayer.keystone.cli.formatters.KeystoneFormatterRegistry; -import org.platformlayer.keystone.cli.guice.CliModule; +import org.platformlayer.metrics.NullMetricsModule; +import org.platformlayer.ops.OpsException; import com.fathomdb.cli.CliContextBase; import com.fathomdb.cli.CliException; +import com.fathomdb.config.ConfigurationImpl; +import com.fathomdb.crypto.KeyStoreUtils; +import com.google.common.base.Joiner; +import com.google.common.collect.Lists; import com.google.inject.ConfigurationException; import com.google.inject.Guice; import com.google.inject.Injector; +import com.google.inject.Module; public class KeystoneCliContext extends CliContextBase { final KeystoneCliOptions options; @@ -24,33 +43,84 @@ public KeystoneCliContext(KeystoneCommandRegistry commandRegistry, KeystoneCliOp @Override public void connect() throws Exception { - this.injector = Guice.createInjector(new CliModule(options)); + Properties properties = options.getConfigurationProperties(); + ConfigurationImpl configuration = ConfigurationImpl.from(new File("."), properties); + + List modules = Lists.newArrayList(); + + modules.add(new ConfigurationModule(configuration)); + modules.add(new KeystoneJdbcModule()); + modules.add(new NullMetricsModule()); + + this.injector = Guice.createInjector(modules); } - public UserRepository getUserRepository() { + public UserDatabase getUserRepository() { try { - return injector.getInstance(UserRepository.class); + return injector.getInstance(UserDatabase.class); } catch (ConfigurationException e) { throw new CliException("Database not configured; must set auth.system.module in configuration"); } } - public OpsUser login() throws RepositoryException { + /** + * Logs in the current user, directly accessing the database + */ + public UserEntity loginDirect() throws RepositoryException { String username = options.getUsername(); String password = options.getPassword(); if (username == null || password == null) { throw new IllegalArgumentException("Must specify username & password"); } - OpsUser user = getUserRepository().findUser(username); - if (user != null) { - if (!user.isPasswordMatch(password)) { - user = null; - } - } + + UserEntity user = (UserEntity) getUserRepository().authenticateWithPassword(username, password); if (user == null) { throw new SecurityException("Credentials were not valid"); } - user.unlockWithPassword(password); return user; } + + public KeystoneCliOptions getOptions() { + return options; + } + + public Certificate[] getCertificateChain(String keystore, String keystoreSecret, String keyAlias) + throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { + if (getOptions().isServerMode()) { + throw new IllegalArgumentException("Files not supported in server mode"); + } + + if (keystoreSecret == null) { + keystoreSecret = KeyStoreUtils.DEFAULT_KEYSTORE_SECRET; + } + + KeyStore keyStore = KeyStoreUtils.load(new File(keystore), keystoreSecret); + + if (keyAlias == null) { + List keyAliases = KeyStoreUtils.getKeyAliases(keyStore); + if (keyAliases.size() == 0) { + throw new CliException("No keys found in keystore"); + } + if (keyAliases.size() != 1) { + System.out.println("Found keys:\n\t" + Joiner.on("\n\t").join(keyAliases)); + throw new CliException("Multiple keys found in keystore; specify --alias"); + } + + keyAlias = keyAliases.get(0); + } + + Certificate[] certificateChain = keyStore.getCertificateChain(keyAlias); + + return certificateChain; + } + + public Certificate[] loadCertificateChain(String certPath) throws IOException, OpsException { + if (getOptions().isServerMode()) { + throw new IllegalArgumentException("Files not supported in server mode"); + } + + CertificateReader reader = new CertificateReader(); + Certificate[] certificates = reader.parse(new File(certPath)); + return certificates; + } } diff --git a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/KeystoneCliOptions.java b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/KeystoneCliOptions.java index 38a41ed2a..cee9f3bf1 100644 --- a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/KeystoneCliOptions.java +++ b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/KeystoneCliOptions.java @@ -8,10 +8,10 @@ import java.util.Properties; import org.kohsuke.args4j.Option; -import org.openstack.utils.Io; -import org.openstack.utils.NoCloseInputStream; import com.fathomdb.cli.CliOptions; +import com.fathomdb.io.IoUtils; +import com.fathomdb.io.NoCloseInputStream; public class KeystoneCliOptions extends CliOptions { @Option(name = "-c", aliases = "--config", usage = "specify configuration file") @@ -40,7 +40,7 @@ public Properties getConfigurationProperties() { if (isServerMode()) { throw new IllegalArgumentException("Must pass config file over stdin in server mode"); } - File file = Io.resolve(configFile); + File file = IoUtils.resolve(configFile); if (!file.exists()) { throw new FileNotFoundException("Configuration file not found: " + file); } @@ -56,7 +56,7 @@ public Properties getConfigurationProperties() { } catch (IOException e) { throw new IllegalArgumentException("Error reading configuration file", e); } finally { - Io.safeClose(is); + IoUtils.safeClose(is); } } diff --git a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/autocomplete/ProjectNameAutoCompleter.java b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/autocomplete/ProjectNameAutoCompleter.java index 6ad84c2d2..6ffa5596e 100644 --- a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/autocomplete/ProjectNameAutoCompleter.java +++ b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/autocomplete/ProjectNameAutoCompleter.java @@ -2,7 +2,7 @@ import java.util.List; -import org.platformlayer.auth.UserRepository; +import org.platformlayer.auth.UserDatabase; import org.platformlayer.keystone.cli.KeystoneCliContext; import com.fathomdb.cli.CliContext; @@ -18,7 +18,7 @@ public List doComplete(CliContext context, String prefix) throws Excepti } KeystoneCliContext keystoneContext = (KeystoneCliContext) context; - UserRepository userRepository = keystoneContext.getUserRepository(); + UserDatabase userRepository = keystoneContext.getUserRepository(); List userIds = userRepository.listAllProjectNames(prefix); addSuffix(userIds, " "); diff --git a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/autocomplete/UserNameAutoCompleter.java b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/autocomplete/UserNameAutoCompleter.java index fac8421b3..1384d601a 100644 --- a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/autocomplete/UserNameAutoCompleter.java +++ b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/autocomplete/UserNameAutoCompleter.java @@ -2,7 +2,7 @@ import java.util.List; -import org.platformlayer.auth.UserRepository; +import org.platformlayer.auth.UserDatabase; import org.platformlayer.keystone.cli.KeystoneCliContext; import com.fathomdb.cli.CliContext; @@ -18,7 +18,7 @@ public List doComplete(CliContext context, String prefix) throws Excepti } KeystoneCliContext keystoneContext = (KeystoneCliContext) context; - UserRepository userRepository = keystoneContext.getUserRepository(); + UserDatabase userRepository = keystoneContext.getUserRepository(); List userIds = userRepository.listAllUserNames(prefix); addSuffix(userIds, " "); diff --git a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/CreateProject.java b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/CreateProject.java index 3b09b48af..6286d63bb 100644 --- a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/CreateProject.java +++ b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/CreateProject.java @@ -2,12 +2,14 @@ import org.kohsuke.args4j.Argument; import org.platformlayer.RepositoryException; -import org.platformlayer.auth.OpsProject; -import org.platformlayer.auth.OpsUser; -import org.platformlayer.auth.UserRepository; +import org.platformlayer.auth.ProjectEntity; +import org.platformlayer.auth.UserDatabase; +import org.platformlayer.auth.UserEntity; + +import com.fathomdb.cli.CliException; public class CreateProject extends KeystoneCommandRunnerBase { - @Argument(index = 0) + @Argument(index = 0, required = true, usage = "Project key") public String projectKey; public CreateProject() { @@ -16,12 +18,16 @@ public CreateProject() { @Override public Object runCommand() throws RepositoryException { - UserRepository userRepository = getContext().getUserRepository(); + UserDatabase userRepository = getContext().getUserRepository(); // We need to login to unlock the user key so we can encrypt the project key! - OpsUser me = getContext().login(); + UserEntity me = getContext().loginDirect(); + + if (projectKey.contains("@@")) { + throw new CliException("Project names with @@ are reserved for system uses"); + } - OpsProject project = userRepository.createProject(projectKey, me); + ProjectEntity project = userRepository.createProject(projectKey, me); return project; } diff --git a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/CreateServiceAccount.java b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/CreateServiceAccount.java new file mode 100644 index 000000000..0f6e34296 --- /dev/null +++ b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/CreateServiceAccount.java @@ -0,0 +1,43 @@ +package org.platformlayer.keystone.cli.commands; + +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; + +import org.kohsuke.args4j.Option; +import org.platformlayer.auth.ServiceAccount; +import org.platformlayer.auth.UserDatabase; + +public class CreateServiceAccount extends KeystoneCommandRunnerBase { + @Option(name = "-k", aliases = "--key", usage = "keystore", required = true) + public String keystore; + + @Option(name = "-s", aliases = "--secret", usage = "keystore secret") + public String keystoreSecret; + + @Option(name = "-a", aliases = "--alias", usage = "key alias") + public String keyAlias; + + public CreateServiceAccount() { + super("create", "serviceaccount"); + } + + @Override + public Object runCommand() throws Exception { + Certificate[] certificateChain = getContext().getCertificateChain(keystore, keystoreSecret, keyAlias); + + X509Certificate cert; + if (certificateChain.length == 1) { + cert = (X509Certificate) certificateChain[0]; + } else { + System.out.println("Certificate chain has length " + certificateChain.length + ", assuming entry 2 is CA"); + cert = (X509Certificate) certificateChain[1]; + } + + UserDatabase userRepository = getContext().getUserRepository(); + + ServiceAccount account = userRepository.createServiceAccount(cert); + + return account; + } + +} diff --git a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/CreateUser.java b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/CreateUser.java index 0e4d670f8..cc05cb6f6 100644 --- a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/CreateUser.java +++ b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/CreateUser.java @@ -1,27 +1,57 @@ package org.platformlayer.keystone.cli.commands; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.cert.Certificate; + import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.Option; import org.platformlayer.RepositoryException; import org.platformlayer.auth.OpsUser; -import org.platformlayer.auth.UserRepository; +import org.platformlayer.auth.UserDatabase; +import org.platformlayer.ops.OpsException; + +import com.fathomdb.cli.CliException; public class CreateUser extends KeystoneCommandRunnerBase { - @Argument(index = 0, required = true) + @Argument(index = 0, required = true, usage = "username") public String username; - @Argument(index = 1, required = true) + @Option(name = "-p", aliases = "--password", usage = "password") public String password; + @Option(name = "-c", aliases = "--cert", usage = "certificate") + public String certPath; + + @Option(name = "-k", aliases = "--key", usage = "keystore") + public String keystore; + + @Option(name = "-s", aliases = "--secret", usage = "keystore secret") + public String keystoreSecret; + + @Option(name = "-a", aliases = "--alias", usage = "key alias") + public String keyAlias; + public CreateUser() { super("create", "user"); } @Override - public Object runCommand() throws RepositoryException { - UserRepository userRepository = getContext().getUserRepository(); + public Object runCommand() throws RepositoryException, GeneralSecurityException, IOException, OpsException { + if (password == null && keystore == null && certPath == null) { + throw new CliException("Either key or password or cert is required"); + } + + UserDatabase userRepository = getContext().getUserRepository(); + Certificate[] certificateChain = null; - OpsUser user = userRepository.createUser(username, password); + if (keystore != null) { + certificateChain = getContext().getCertificateChain(keystore, keystoreSecret, keyAlias); + } else if (certPath != null) { + certificateChain = getContext().loadCertificateChain(certPath); + } + OpsUser user = userRepository.createUser(username, password, certificateChain); return user; } diff --git a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/JoinProject.java b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/JoinProject.java index 64f043ad6..3e382c894 100644 --- a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/JoinProject.java +++ b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/JoinProject.java @@ -1,19 +1,21 @@ package org.platformlayer.keystone.cli.commands; import java.io.IOException; - -import javax.crypto.SecretKey; +import java.util.Collections; import org.kohsuke.args4j.Argument; import org.platformlayer.RepositoryException; -import org.platformlayer.auth.OpsProject; -import org.platformlayer.auth.OpsUser; -import org.platformlayer.auth.UserRepository; +import org.platformlayer.auth.ProjectEntity; +import org.platformlayer.auth.UserDatabase; +import org.platformlayer.auth.UserEntity; import org.platformlayer.auth.crypto.SecretStore; import org.platformlayer.keystone.cli.model.ProjectName; import org.platformlayer.keystone.cli.model.UserName; +import org.platformlayer.model.RoleId; import com.fathomdb.cli.CliException; +import com.fathomdb.crypto.CryptoKey; +import com.google.common.base.Strings; public class JoinProject extends KeystoneCommandRunnerBase { @Argument(index = 0, required = true, metaVar = "username") @@ -22,30 +24,37 @@ public class JoinProject extends KeystoneCommandRunnerBase { @Argument(index = 1, required = true, metaVar = "project") public ProjectName projectKey; + @Argument(index = 2, required = true, metaVar = "role") + public String roleKey; + public JoinProject() { super("join", "project"); } @Override public Object runCommand() throws RepositoryException, IOException { - UserRepository userRepository = getContext().getUserRepository(); + UserDatabase userRepository = getContext().getUserRepository(); - OpsUser me = getContext().login(); - OpsProject project = userRepository.findProjectByKey(projectKey.getKey()); + UserEntity me = getContext().loginDirect(); + ProjectEntity project = userRepository.findProjectByKey(projectKey.getKey()); if (project == null) { throw new CliException("Project not found: " + projectKey.getKey()); } SecretStore secretStore = new SecretStore(project.secretData); - SecretKey projectKey = secretStore.getSecretFromUser(me); - if (projectKey == null) { + CryptoKey projectSecret = secretStore.getSecretFromUser(me); + if (projectSecret == null) { String msg = "Cannot retrieve project secret."; - msg += " Is " + me.key + " a member of " + project.key + "?"; + msg += " Is " + me.key + " a member of " + project.getName() + "?"; throw new CliException(msg); } - userRepository.addUserToProject(username.getKey(), project.key, projectKey); + if (Strings.isNullOrEmpty(roleKey)) { + throw new CliException("Role is required"); + } + RoleId role = new RoleId(roleKey); + userRepository.addUserToProject(username.getKey(), project.getName(), projectSecret, + Collections.singletonList(role)); return project; } - } diff --git a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/KeystoneCommandRegistry.java b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/KeystoneCommandRegistry.java index e60f1cc58..03ccc8136 100644 --- a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/KeystoneCommandRegistry.java +++ b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/KeystoneCommandRegistry.java @@ -1,17 +1,18 @@ package org.platformlayer.keystone.cli.commands; -import org.apache.log4j.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.fathomdb.cli.commands.AutoComplete; import com.fathomdb.cli.commands.CommandRegistryBase; public class KeystoneCommandRegistry extends CommandRegistryBase { - static final Logger log = Logger.getLogger(KeystoneCommandRegistry.class); + static final Logger log = LoggerFactory.getLogger(KeystoneCommandRegistry.class); public KeystoneCommandRegistry() { addCommand(new AutoComplete()); - discoverCommands(getClass().getPackage()); + discoverCommands(); } } diff --git a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/ListProjects.java b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/ListProjects.java index c3f11cff6..c3cf436e3 100644 --- a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/ListProjects.java +++ b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/ListProjects.java @@ -2,8 +2,8 @@ import org.kohsuke.args4j.Argument; import org.platformlayer.RepositoryException; -import org.platformlayer.auth.OpsUser; -import org.platformlayer.auth.UserRepository; +import org.platformlayer.auth.UserDatabase; +import org.platformlayer.auth.UserEntity; import org.platformlayer.keystone.cli.model.UserName; public class ListProjects extends KeystoneCommandRunnerBase { @@ -16,12 +16,12 @@ public ListProjects() { @Override public Object runCommand() throws RepositoryException { - UserRepository userRepository = getContext().getUserRepository(); + UserDatabase userRepository = getContext().getUserRepository(); // if (username == null) { // return userRepository.listAllProjectNames(null); // } else { - OpsUser user = userRepository.findUser(username.getKey()); + UserEntity user = (UserEntity) userRepository.findUser(username.getKey()); if (user == null) { throw new IllegalArgumentException("User not found"); } diff --git a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/ListServiceAccounts.java b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/ListServiceAccounts.java new file mode 100644 index 000000000..93bef7e34 --- /dev/null +++ b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/ListServiceAccounts.java @@ -0,0 +1,32 @@ +package org.platformlayer.keystone.cli.commands; + +import java.util.List; + +import org.kohsuke.args4j.Option; +import org.platformlayer.RepositoryException; +import org.platformlayer.auth.ServiceAccountEntity; +import org.platformlayer.auth.UserDatabase; + +import com.fathomdb.utils.Hex; + +public class ListServiceAccounts extends KeystoneCommandRunnerBase { + @Option(name = "-k", aliases = "--key", usage = "Public key") + public String publicKey; + + public ListServiceAccounts() { + super("list", "serviceaccounts"); + } + + @Override + public Object runCommand() throws RepositoryException { + UserDatabase userRepository = getContext().getUserRepository(); + + byte[] publicKeyBytes = null; + if (publicKey != null) { + publicKeyBytes = Hex.fromHex(publicKey); + } + List serviceAcccounts = userRepository.listAllServiceAccounts(publicKeyBytes); + return serviceAcccounts; + } + +} diff --git a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/ListUsers.java b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/ListUsers.java index c7531dd0d..d3e28ba4e 100644 --- a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/ListUsers.java +++ b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/commands/ListUsers.java @@ -4,7 +4,7 @@ import org.kohsuke.args4j.Argument; import org.platformlayer.RepositoryException; -import org.platformlayer.auth.UserRepository; +import org.platformlayer.auth.UserDatabase; public class ListUsers extends KeystoneCommandRunnerBase { @Argument(index = 0) @@ -16,7 +16,7 @@ public ListUsers() { @Override public Object runCommand() throws RepositoryException { - UserRepository userRepository = getContext().getUserRepository(); + UserDatabase userRepository = getContext().getUserRepository(); List users = userRepository.listAllUserNames(prefix); return users; diff --git a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/formatters/KeystoneFormatterRegistry.java b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/formatters/KeystoneFormatterRegistry.java index 7fb9b4ee6..9f58fd036 100644 --- a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/formatters/KeystoneFormatterRegistry.java +++ b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/formatters/KeystoneFormatterRegistry.java @@ -6,7 +6,7 @@ public class KeystoneFormatterRegistry extends FormatterRegistryBase { public KeystoneFormatterRegistry() { addDefaultFormatters(); - discoverFormatters(getClass().getPackage()); + discoverFormatters(); } } diff --git a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/formatters/OpsProjectFormatter.java b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/formatters/OpsProjectFormatter.java index 51cbce1d5..b731a9da9 100644 --- a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/formatters/OpsProjectFormatter.java +++ b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/formatters/OpsProjectFormatter.java @@ -3,23 +3,24 @@ import java.io.IOException; import java.util.LinkedHashMap; -import org.platformlayer.auth.OpsProject; +import org.platformlayer.auth.ProjectInfo; +import com.fathomdb.cli.CliContext; import com.fathomdb.cli.formatter.SimpleFormatter; import com.fathomdb.cli.output.OutputSink; import com.google.common.collect.Maps; -public class OpsProjectFormatter extends SimpleFormatter { +public class OpsProjectFormatter extends SimpleFormatter { public OpsProjectFormatter() { - super(OpsProject.class); + super(ProjectInfo.class); } @Override - public void visit(OpsProject o, OutputSink sink) throws IOException { + public void visit(CliContext context, ProjectInfo o, OutputSink sink) throws IOException { LinkedHashMap values = Maps.newLinkedHashMap(); - values.put("key", o.key); + values.put("name", o.getName()); sink.outputRow(values); } diff --git a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/formatters/OpsUserFormatter.java b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/formatters/OpsUserFormatter.java index 427e754f3..ab983e884 100644 --- a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/formatters/OpsUserFormatter.java +++ b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/formatters/OpsUserFormatter.java @@ -5,6 +5,7 @@ import org.platformlayer.auth.OpsUser; +import com.fathomdb.cli.CliContext; import com.fathomdb.cli.formatter.SimpleFormatter; import com.fathomdb.cli.output.OutputSink; import com.google.common.collect.Maps; @@ -16,11 +17,11 @@ public OpsUserFormatter() { } @Override - public void visit(OpsUser o, OutputSink sink) throws IOException { + public void visit(CliContext context, OpsUser o, OutputSink sink) throws IOException { LinkedHashMap values = Maps.newLinkedHashMap(); - values.put("id", o.id); - values.put("key", o.key); + // values.put("id", o.id); + values.put("user", o.toString()); sink.outputRow(values); } diff --git a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/formatters/ServiceAccountFormatter.java b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/formatters/ServiceAccountFormatter.java new file mode 100644 index 000000000..59bfc885b --- /dev/null +++ b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/formatters/ServiceAccountFormatter.java @@ -0,0 +1,32 @@ +package org.platformlayer.keystone.cli.formatters; + +import java.io.IOException; +import java.util.LinkedHashMap; + +import org.platformlayer.auth.ServiceAccount; +import org.platformlayer.auth.ServiceAccountEntity; + +import com.fathomdb.cli.CliContext; +import com.fathomdb.cli.formatter.SimpleFormatter; +import com.fathomdb.cli.output.OutputSink; +import com.fathomdb.utils.Hex; +import com.google.common.collect.Maps; + +public class ServiceAccountFormatter extends SimpleFormatter { + + public ServiceAccountFormatter() { + super(ServiceAccount.class); + } + + @Override + public void visit(CliContext context, ServiceAccount o, OutputSink sink) throws IOException { + LinkedHashMap values = Maps.newLinkedHashMap(); + + ServiceAccountEntity entity = (ServiceAccountEntity) o; + + values.put("subject", entity.subject); + values.put("publicKeyData", Hex.toHex(entity.publicKeyData)); + + sink.outputRow(values); + } +} diff --git a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/guice/CliModule.java b/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/guice/CliModule.java deleted file mode 100644 index a971d1415..000000000 --- a/auth/keystone-cli/src/main/java/org/platformlayer/keystone/cli/guice/CliModule.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.platformlayer.keystone.cli.guice; - -import java.util.Properties; - -import org.platformlayer.keystone.cli.KeystoneCliOptions; - -import com.google.inject.AbstractModule; -import com.google.inject.Module; -import com.google.inject.name.Names; - -public class CliModule extends AbstractModule { - - private final KeystoneCliOptions options; - - public CliModule(KeystoneCliOptions options) { - this.options = options; - } - - @Override - protected void configure() { - Properties config = options.getConfigurationProperties(); - Names.bindProperties(binder(), config); - - bindAuthenticationModules(config); - } - - private void bindAuthenticationModules(Properties config) { - String userProvider = config.getProperty("auth.user.module"); - if (userProvider != null) { - installModule(userProvider); - } - String systemProvider = config.getProperty("auth.system.module"); - if (systemProvider != null) { - if (!systemProvider.equals(userProvider)) { - installModule(systemProvider); - } - } - } - - private void installModule(String moduleClassName) { - try { - Class moduleClass = Class.forName(moduleClassName); - Module module = (Module) moduleClass.newInstance(); - binder().install(module); - } catch (Exception e) { - throw new IllegalStateException("Error loading class: " + moduleClassName); - } - } - -} diff --git a/auth/pom.xml b/auth/pom.xml index 77d2bdb13..3f40174f5 100644 --- a/auth/pom.xml +++ b/auth/pom.xml @@ -8,21 +8,11 @@ 1.0-SNAPSHOT - 1.0-SNAPSHOT - org.platformlayer keystone-parent PlatformLayer :: Auth :: Parent pom - - 4.8.2 - 7.4.1.v20110513 - 1.10 - 3.0 - - - keystone-api keystone-cli server-shared server-admin @@ -32,13 +22,6 @@ - - - org.slf4j - slf4j-log4j12 - 1.6.1 - - junit junit @@ -46,8 +29,6 @@ test - - diff --git a/auth/server-admin/AuthAdminServer.launch b/auth/server-admin/AuthAdminServer.launch deleted file mode 100644 index bcfe399d3..000000000 --- a/auth/server-admin/AuthAdminServer.launch +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/auth/server-admin/logback.xml b/auth/server-admin/logback.xml new file mode 100644 index 000000000..c9dae7427 --- /dev/null +++ b/auth/server-admin/logback.xml @@ -0,0 +1,20 @@ + + + + + + %d [%thread] %-5level %logger{35} - %msg %n + + + + + + + + + + + + + \ No newline at end of file diff --git a/auth/server-admin/pom.xml b/auth/server-admin/pom.xml index a4b93d147..318ec7357 100644 --- a/auth/server-admin/pom.xml +++ b/auth/server-admin/pom.xml @@ -9,16 +9,61 @@ keystone-webapp-admin - Keystone :: Server :: Admin + + postgresql + postgresql + + org.platformlayer keystone-webapp-shared ${version.project} - + + ch.qos.logback + logback-classic + + + + org.platformlayer + metrics-client + + + + com.yammer.metrics + metrics-jetty + + + + org.apache.tomcat + tomcat-jdbc + + + + + + maven-assembly-plugin + 2.3 + + + src/main/assembly/tarfile.xml + + + + + make-assembly + package + + single + + + + + + diff --git a/auth/server-admin/src/main/assembly/tarfile.xml b/auth/server-admin/src/main/assembly/tarfile.xml new file mode 100644 index 000000000..4d09f8b85 --- /dev/null +++ b/auth/server-admin/src/main/assembly/tarfile.xml @@ -0,0 +1,21 @@ + + bin + + tar.gz + + + false + + + + + / + true + false + runtime + + + \ No newline at end of file diff --git a/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/KeychainResource.java b/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/KeychainResource.java new file mode 100644 index 000000000..095565e0d --- /dev/null +++ b/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/KeychainResource.java @@ -0,0 +1,96 @@ +package org.openstack.keystone.resources.admin; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; + +import org.platformlayer.auth.AuthenticatorException; +import org.platformlayer.auth.ProjectEntity; +import org.platformlayer.auth.UserEntity; +import org.platformlayer.auth.UserProjectEntity; +import org.platformlayer.auth.model.CertificateChainInfo; +import org.platformlayer.auth.model.ValidateAccess; +import org.platformlayer.auth.model.ValidateTokenResponse; +import org.platformlayer.auth.resources.Mapping; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Path("v2.0/keychain") +public class KeychainResource extends RootResource { + private static final Logger log = LoggerFactory.getLogger(KeychainResource.class); + + @POST + public ValidateTokenResponse authorizeCertificateChain(@QueryParam("project") String project, + CertificateChainInfo chain) { + try { + requireSystemAccess(); + } catch (AuthenticatorException e) { + log.warn("Error while checking system token", e); + throwInternalError(); + } + + UserEntity userEntity = null; + try { + boolean unlock = false; + userEntity = userAuthenticator.findUserFromKeychain(chain, unlock); + } catch (AuthenticatorException e) { + log.warn("Error while fetching user", e); + throwInternalError(); + } + + if (userEntity == null) { + throw404NotFound(); + } + + ValidateTokenResponse response = new ValidateTokenResponse(); + response.access = new ValidateAccess(); + response.access.user = Mapping.mapToUserValidation(userEntity); + + // response.access.token = new Token(); + // response.access.token.expires = checkTokenInfo.expiration; + // response.access.token.id = checkToken; + + String checkProject = project; + + if (checkProject != null) { + ProjectEntity projectEntity = null; + + try { + projectEntity = userAuthenticator.findProject(checkProject); + } catch (AuthenticatorException e) { + log.warn("Error while fetching project", e); + throwInternalError(); + } + + if (projectEntity == null) { + throw404NotFound(); + } + + // Note that we do not unlock the user / project; we don't have any secret material + // TODO: We could return stuff encrypted with the user's public key + // projectEntity.unlockWithUser(userEntity); + // + // if (!projectEntity.isSecretValid()) { + // throw404NotFound(); + // } + + UserProjectEntity userProject = null; + try { + userProject = userAuthenticator.findUserProject(userEntity, projectEntity); + } catch (AuthenticatorException e) { + log.warn("Error while fetching project", e); + throwInternalError(); + } + + if (userProject == null) { + // Not a member of project + throw404NotFound(); + } + + response.access.project = Mapping.mapToProject(projectEntity); + response.access.project.roles = Mapping.mapToRoles(userProject.getRoles()); + } + + return response; + } +} diff --git a/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/PkiResource.java b/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/PkiResource.java new file mode 100644 index 000000000..94346febf --- /dev/null +++ b/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/PkiResource.java @@ -0,0 +1,123 @@ +package org.openstack.keystone.resources.admin; + +import java.security.cert.X509Certificate; +import java.util.List; + +import javax.inject.Inject; +import javax.ws.rs.POST; +import javax.ws.rs.Path; + +import org.platformlayer.auth.AuthenticatorException; +import org.platformlayer.auth.ProjectEntity; +import org.platformlayer.auth.model.SignCertificateRequest; +import org.platformlayer.auth.model.SignCertificateResponse; +import org.platformlayer.auth.services.PkiService; +import org.platformlayer.crypto.CertificateUtils; +import org.platformlayer.ops.OpsException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fathomdb.crypto.FathomdbCrypto; +import com.google.common.collect.Lists; + +@Path("/pki") +public class PkiResource extends RootResource { + private static final Logger log = LoggerFactory.getLogger(PkiResource.class); + + @Inject + PkiService pki; + + @POST + @Path("csr") + public SignCertificateResponse signCertificate(SignCertificateRequest request) { + try { + requireSystemAccess(); + } catch (AuthenticatorException e) { + log.warn("Error while checking system token", e); + throwInternalError(); + } + + // TokenInfo checkTokenInfo = tokenService.decodeToken(checkToken); + // if (checkTokenInfo == null || checkTokenInfo.hasExpired()) { + // throw404NotFound(); + // } + // + // UserEntity user = null; + // try { + // user = userAuthenticator.getUserFromToken(checkTokenInfo.userId, checkTokenInfo.tokenSecret); + // } catch (AuthenticatorException e) { + // log.warn("Error while fetching user", e); + // throwInternalError(); + // } + // + // if (user == null) { + // throw404NotFound(); + // } + + String projectKey = request.project; + + ProjectEntity project = null; + + try { + project = userAuthenticator.findProject(projectKey); + } catch (AuthenticatorException e) { + log.warn("Error while fetching project", e); + throwInternalError(); + } + + if (project == null) { + throw404NotFound(); + } + + project.setProjectSecret(FathomdbCrypto.deserializeKey(request.projectSecret)); + + // Note that we do not unlock the user / project; we don't have any secret material + // TODO: We could return stuff encrypted with the user's public key + // projectEntity.unlockWithUser(userEntity); + // + // if (!projectEntity.isSecretValid()) { + // throw404NotFound(); + // } + + // UserProjectEntity userProject = null; + // try { + // userProject = userAuthenticator.findUserProject(user, project); + // } catch (AuthenticatorException e) { + // log.warn("Error while fetching project", e); + // throwInternalError(); + // } + // + // if (userProject == null) { + // // Not a member of project + // throw404NotFound(); + // } + // + // boolean isOwner = false; + // for (RoleId role : userProject.getRoles()) { + // if (role.equals(RoleId.OWNER)) { + // isOwner = true; + // } + // } + // + // if (!isOwner) { + // throwUnauthorized(); + // } + + List certificates = null; + try { + certificates = pki.signCsr(project, request.csr); + } catch (OpsException e) { + log.warn("Error while signing CSR", e); + throwInternalError(); + } + + SignCertificateResponse response = new SignCertificateResponse(); + + response.certificates = Lists.newArrayList(); + for (X509Certificate cert : certificates) { + response.certificates.add(CertificateUtils.toPem(cert)); + } + return response; + } + +} diff --git a/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/RootResource.java b/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/RootResource.java new file mode 100644 index 000000000..4cabac2bf --- /dev/null +++ b/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/RootResource.java @@ -0,0 +1,61 @@ +package org.openstack.keystone.resources.admin; + +import java.security.cert.X509Certificate; + +import javax.inject.Inject; + +import org.platformlayer.auth.AuthenticatorException; +import org.platformlayer.auth.ServiceAccount; +import org.platformlayer.auth.model.CertificateChainInfo; +import org.platformlayer.auth.model.CertificateInfo; +import org.platformlayer.auth.resources.PlatformlayerAuthResourceBase; +import org.platformlayer.auth.services.SystemAuthenticator; +import org.platformlayer.auth.services.TokenService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fathomdb.crypto.Certificates; +import com.fathomdb.utils.Hex; + +public class RootResource extends PlatformlayerAuthResourceBase { + private static final Logger log = LoggerFactory.getLogger(RootResource.class); + + @Inject + protected SystemAuthenticator systemAuthenticator; + + @Inject + protected TokenService tokenService; + + protected void requireSystemAccess() throws AuthenticatorException { + X509Certificate[] certChain = getCertificateChain(); + if (certChain != null && certChain.length != 0) { + CertificateChainInfo chain = new CertificateChainInfo(); + for (X509Certificate cert : certChain) { + CertificateInfo info = new CertificateInfo(); + + info.publicKey = Hex.toHex(cert.getPublicKey().getEncoded()); + info.subjectDN = Certificates.getSubject(cert); + + // Md5Hash hash = OpenSshUtils.getSignature(cert.getPublicKey()); + // certificateInfo.setPublicKeyHash(hash.toHex()); + + chain.certificates.add(info); + } + + ServiceAccount auth = systemAuthenticator.authenticate(chain); + if (auth != null) { + log.debug("Certificate authentication SUCCESS for " + chain); + return; + } + + log.debug("Certificate authentication FAIL for " + chain); + } else { + log.debug("Certificate authentication FAIL (no certificate presented)"); + } + + throwUnauthorized(); + + // return myTokenInfo; + } + +} diff --git a/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/ServicesResource.java b/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/ServicesResource.java new file mode 100644 index 000000000..81cbd2596 --- /dev/null +++ b/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/ServicesResource.java @@ -0,0 +1,42 @@ +package org.openstack.keystone.resources.admin; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; + +import org.platformlayer.auth.AuthenticatorException; +import org.platformlayer.auth.ServiceAccountEntity; +import org.platformlayer.auth.model.CheckServiceAccessRequest; +import org.platformlayer.auth.model.CheckServiceAccessResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Path("/services") +public class ServicesResource extends RootResource { + private static final Logger log = LoggerFactory.getLogger(ServicesResource.class); + + @POST + @Path("check") + public CheckServiceAccessResponse checkServiceAccess(CheckServiceAccessRequest request) { + try { + requireSystemAccess(); + } catch (AuthenticatorException e) { + log.warn("Error while checking system token", e); + throwInternalError(); + } + + ServiceAccountEntity serviceAccount = null; + try { + serviceAccount = systemAuthenticator.authenticate(request.chain); + } catch (AuthenticatorException e) { + log.warn("Error while authenticating chain", e); + throwInternalError(); + } + + CheckServiceAccessResponse response = new CheckServiceAccessResponse(); + if (serviceAccount != null) { + response.serviceAccount = serviceAccount.subject; + } + return response; + } + +} diff --git a/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/TenantsResource.java b/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/TenantsResource.java deleted file mode 100644 index 1565a7400..000000000 --- a/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/TenantsResource.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.openstack.keystone.resources.admin; - -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; - -import org.openstack.keystone.model.Tenant; -import org.openstack.keystone.model.TenantsList; -import org.openstack.keystone.resources.KeystoneResourceBase; - -public class TenantsResource extends KeystoneResourceBase { - @GET - @Produces({ APPLICATION_XML, APPLICATION_JSON }) - public TenantsList listTenants(@QueryParam("name") String tenantName) { - throw new UnsupportedOperationException(); - // TokenInfo myToken = requireAdminToken(); - // - // if (tenantName != null) { - // // SPECBUG: Calls should always return the same schema - // throw new UnsupportedOperationException(); - // } - // - // TenantsList tenants = authentication.listTenants(myToken, null); - // return tenants; - } - - @GET - @Path("{tenantId}/users/{userId}/roles") - @Produces({ APPLICATION_XML, APPLICATION_JSON }) - public void getRoles(@PathParam("tenantId") String tenantId, @PathParam("userId") String userId) { - throw new UnsupportedOperationException(); - - // TokenInfo myToken = requireAdminToken(); - // - // TenantsList tenants = authentication.listTenants(myToken, null); - // return tenants; - } - - @GET - @Path("{tenantId}/endpoints") - @Produces({ APPLICATION_XML, APPLICATION_JSON }) - public void getEndpoints(@HeaderParam("X-Auth-Token") String tokenId, @PathParam("tenantId") String tenantId) { - throw new UnsupportedOperationException(); - } - - @GET - @Path("{tenantId}") - @Produces({ APPLICATION_XML, APPLICATION_JSON }) - public Tenant getTenant(@PathParam("tenantId") String tenantId) { - throw new UnsupportedOperationException(); - - // TokenInfo myToken = requireAdminToken(); - // - // TenantsList tenants = authentication.listTenants(myToken, tenantId); - // if (isNullOrEmpty(tenants.tenant)) { - // throw404NotFound(); - // } - // if (tenants.tenant.size() != 1) { - // throw new IllegalStateException("Unexpected number of items found"); - // } - // return tenants.tenant.get(0); - } -} diff --git a/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/TokensResource.java b/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/TokensResource.java index 29c352146..72939f4ca 100644 --- a/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/TokensResource.java +++ b/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/TokensResource.java @@ -1,81 +1,98 @@ package org.openstack.keystone.resources.admin; -import javax.ws.rs.Consumes; import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; -import org.apache.log4j.Logger; -import org.openstack.keystone.model.Access; -import org.openstack.keystone.model.Auth; -import org.openstack.keystone.model.UserValidation; -import org.openstack.keystone.model.ValidateAccess; -import org.openstack.keystone.model.ValidateTokenResponse; -import org.openstack.keystone.resources.KeystoneResourceBase; -import org.openstack.keystone.resources.Mapping; -import org.openstack.keystone.services.AuthenticatorException; -import org.openstack.keystone.services.TokenInfo; -import org.openstack.keystone.services.UserInfo; - -import com.google.common.base.Objects; +import org.platformlayer.auth.AuthenticatorException; +import org.platformlayer.auth.ProjectEntity; +import org.platformlayer.auth.UserEntity; +import org.platformlayer.auth.UserProjectEntity; +import org.platformlayer.auth.model.Token; +import org.platformlayer.auth.model.ValidateAccess; +import org.platformlayer.auth.model.ValidateTokenResponse; +import org.platformlayer.auth.resources.Mapping; +import org.platformlayer.auth.services.TokenInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @Path("v2.0/tokens") -public class TokensResource extends KeystoneResourceBase { - static final Logger log = Logger.getLogger(TokensResource.class); - - @POST - @Produces({ APPLICATION_XML, APPLICATION_JSON }) - @Consumes({ APPLICATION_XML, APPLICATION_JSON }) - public Access authenticate(Auth request) { - throw new UnsupportedOperationException(); - - // boolean isSystem = true; - // TokenInfo tokenInfo = doAuthenticate(isSystem, request); - } +public class TokensResource extends RootResource { + private static final Logger log = LoggerFactory.getLogger(TokensResource.class); @GET // @HEAD support is automatic from the @GET @Path("{tokenId}") - public ValidateTokenResponse validateToken(@HeaderParam("X-Auth-Token") String myToken, - @PathParam("tokenId") String checkToken, @QueryParam("belongsTo") String tenantId) { - requireSystemToken(); - - TokenInfo checkTokenInfo = authentication.validateToken(false, checkToken); - if (checkTokenInfo == null) { - throw404NotFound(); + public ValidateTokenResponse validateToken(@PathParam("tokenId") String checkToken, + @QueryParam("project") String project) { + try { + requireSystemAccess(); + } catch (AuthenticatorException e) { + log.warn("Error while checking system token", e); + throwInternalError(); } - if (tenantId != null) { - if (!Objects.equal(tenantId, checkTokenInfo.scope)) { - throw404NotFound(); - } + TokenInfo checkTokenInfo = tokenService.decodeToken(checkToken); + if (checkTokenInfo == null || checkTokenInfo.hasExpired()) { + throw404NotFound(); } - UserInfo userInfo = null; + UserEntity userEntity = null; try { - userInfo = authentication.getUserInfo(checkTokenInfo.isSystem(), checkTokenInfo.userId, - checkTokenInfo.tokenSecret); + userEntity = userAuthenticator.getUserFromToken(checkTokenInfo.userId, checkTokenInfo.tokenSecret); } catch (AuthenticatorException e) { - log.warn("Error while listing groups", e); + log.warn("Error while fetching user", e); throwInternalError(); } ValidateTokenResponse response = new ValidateTokenResponse(); response.access = new ValidateAccess(); - response.access.user = new UserValidation(); - response.access.user.id = userInfo.userId; - response.access.user.name = userInfo.username; - response.access.user.roles = authentication.getRoles(userInfo, checkTokenInfo.scope); + response.access.user = Mapping.mapToUserValidation(userEntity); - response.access.user.secret = userInfo.secret; - - response.access.token = Mapping.mapToResponse(checkTokenInfo); + response.access.token = new Token(); + response.access.token.expires = checkTokenInfo.expiration; response.access.token.id = checkToken; + String checkProject = project; + + if (checkProject != null) { + ProjectEntity projectEntity = null; + + try { + projectEntity = userAuthenticator.findProject(checkProject); + } catch (AuthenticatorException e) { + log.warn("Error while fetching project", e); + throwInternalError(); + } + + if (projectEntity == null) { + throw404NotFound(); + } + + projectEntity.unlockWithUser(userEntity); + + if (!projectEntity.isSecretValid()) { + throw404NotFound(); + } + + UserProjectEntity userProject = null; + try { + userProject = userAuthenticator.findUserProject(userEntity, projectEntity); + } catch (AuthenticatorException e) { + log.warn("Error while fetching project", e); + throwInternalError(); + } + + if (userProject == null) { + // Not a member of project + throw404NotFound(); + } + + response.access.project = Mapping.mapToProject(projectEntity); + response.access.project.roles = Mapping.mapToRoles(userProject.getRoles()); + } + return response; } diff --git a/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/UsersResource.java b/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/UsersResource.java deleted file mode 100644 index 4017f906d..000000000 --- a/auth/server-admin/src/main/java/org/openstack/keystone/resources/admin/UsersResource.java +++ /dev/null @@ -1,95 +0,0 @@ -//package org.openstack.keystone.resources.admin; -// -//import javax.ws.rs.GET; -//import javax.ws.rs.Path; -//import javax.ws.rs.Produces; -//import javax.ws.rs.QueryParam; -// -//import org.apache.log4j.Logger; -//import org.openstack.keystone.model.User; -//import org.openstack.keystone.resources.KeystoneResourceBase; -//import org.openstack.keystone.resources.Mapping; -//import org.openstack.keystone.services.AuthenticatorException; -//import org.openstack.keystone.services.UserInfo; -// -//@Path("users") -//public class UsersResource extends KeystoneResourceBase { -// static final Logger log = Logger.getLogger(UsersResource.class); -// -// @GET -// @Path("{userId}/roles") -// @Produces({ APPLICATION_XML, APPLICATION_JSON }) -// public RoleList getUserRoles(@PathParam("userId") String userId) { -// requireSystemToken(); -// -// boolean isSystemUser = false; -// UserInfo userInfo = null; -// try { -// userInfo = authentication.getUserInfo(isSystemUser, userId); -// } catch (AuthenticatorException e) { -// // An exception indicates something went wrong (i.e. not just bad credentials) -// log.warn("Error while getting user info", e); -// throwInternalError(); -// } -// -// if (userInfo == null) { -// throw404NotFound(); -// } -// -// List roles = authentication.getRoles(userInfo, null); -// List globalRoles = Lists.newArrayList(); -// for (Role role : roles) { -// if (role.tenantId != null) -// continue; -// globalRoles.add(role); -// } -// return Mapping.mapToRoles(globalRoles); -// } -// -// @GET -// @Path("{userId}") -// @Produces({ APPLICATION_XML, APPLICATION_JSON }) -// public User getUserById(@PathParam("userId") String userId) { -// requireSystemToken(); -// -// boolean isSystemUser = false; -// -// UserInfo userInfo = null; -// try { -// userInfo = authentication.getUserInfo(isSystemUser, userId); -// } catch (AuthenticatorException e) { -// // An exception indicates something went wrong (i.e. not just bad credentials) -// log.warn("Error while getting user info", e); -// throwInternalError(); -// } -// if (userInfo == null) { -// throw404NotFound(); -// } -// -// return Mapping.mapToUser(userInfo); -// } -// -// @GET -// @Produces({ APPLICATION_XML, APPLICATION_JSON }) -// public User getUserByUsername(@QueryParam("username") String username) { -// requireSystemToken(); -// -// boolean isSystemUser = false; -// -// UserInfo userInfo = null; -// try { -// userInfo = authentication.getUserInfoByUsername(isSystemUser, username); -// } catch (AuthenticatorException e) { -// // An exception indicates something went wrong (i.e. not just bad credentials) -// log.warn("Error while getting user info", e); -// throwInternalError(); -// } -// -// if (userInfo == null) { -// throw404NotFound(); -// } -// -// return Mapping.mapToUser(userInfo); -// } -// -// } diff --git a/auth/server-admin/src/main/java/org/openstack/keystone/server/AdminServerConfig.java b/auth/server-admin/src/main/java/org/openstack/keystone/server/AdminServerConfig.java deleted file mode 100644 index bb4332b7d..000000000 --- a/auth/server-admin/src/main/java/org/openstack/keystone/server/AdminServerConfig.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.openstack.keystone.server; - -import java.util.Map; - -import org.openstack.keystone.resources.admin.TokensResource; - -import com.google.common.collect.Maps; -import com.google.inject.Guice; -import com.google.inject.Injector; -import com.google.inject.servlet.GuiceServletContextListener; -import com.sun.jersey.api.core.PackagesResourceConfig; -import com.sun.jersey.guice.JerseyServletModule; -import com.sun.jersey.guice.spi.container.servlet.GuiceContainer; - -public class AdminServerConfig extends GuiceServletContextListener { - - @Override - protected Injector getInjector() { - return Guice.createInjector(new GuiceAuthenticationConfig(), new JerseyServletModule() { - @Override - protected void configureServlets() { - - boolean isAdmin = false; - if (isAdmin) { - throw new UnsupportedOperationException(); - } else { - bind(TokensResource.class); - - Map params = Maps.newHashMap(); - params.put(PackagesResourceConfig.PROPERTY_PACKAGES, - "org.openstack.keystone.jaxrs;org.codehaus.jackson.jaxrs"); - serve("/*").with(GuiceContainer.class, params); - } - } - }); - } -} diff --git a/auth/server-admin/src/main/java/org/openstack/keystone/server/KeystoneAdminServer.java b/auth/server-admin/src/main/java/org/openstack/keystone/server/KeystoneAdminServer.java index eb92fe581..74073470a 100644 --- a/auth/server-admin/src/main/java/org/openstack/keystone/server/KeystoneAdminServer.java +++ b/auth/server-admin/src/main/java/org/openstack/keystone/server/KeystoneAdminServer.java @@ -1,48 +1,91 @@ package org.openstack.keystone.server; import java.util.EnumSet; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; -import org.eclipse.jetty.server.DispatcherType; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.servlet.DefaultServlet; -import org.eclipse.jetty.servlet.FilterHolder; -import org.eclipse.jetty.servlet.ServletContextHandler; +import org.openstack.keystone.resources.admin.KeychainResource; +import org.openstack.keystone.resources.admin.PkiResource; +import org.openstack.keystone.resources.admin.ServicesResource; +import org.openstack.keystone.resources.admin.TokensResource; import org.platformlayer.WellKnownPorts; +import org.platformlayer.auth.KeystoneJdbcModule; +import org.platformlayer.auth.keystone.KeystoneOpsSystemModule; +import org.platformlayer.auth.server.GuiceAuthenticationConfig; +import org.platformlayer.cache.CacheModule; +import org.platformlayer.config.ConfigurationModule; +import org.platformlayer.metrics.MetricReporter; +import org.platformlayer.metrics.client.codahale.CodahaleMetricsModule; -import com.google.inject.servlet.GuiceFilter; +import com.fathomdb.server.http.SslOption; +import com.fathomdb.server.http.WebServerBuilder; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Module; +import com.sun.jersey.api.core.PackagesResourceConfig; +import com.sun.jersey.guice.JerseyServletModule; +import com.sun.jersey.guice.spi.container.servlet.GuiceContainer; public class KeystoneAdminServer { - private Server server; + private Server jettyServer; + + @Inject + WebServerBuilder serverBuilder; + + @Inject + Injector injector; + + @Inject + MetricReporter metricReporter; public static void main(String[] args) throws Exception { - KeystoneAdminServer server = new KeystoneAdminServer(); - server.start(WellKnownPorts.PORT_PLATFORMLAYER_AUTH_ADMIN); - } + List modules = Lists.newArrayList(); + modules.add(new ConfigurationModule()); + modules.add(new CacheModule()); + modules.add(new GuiceAuthenticationConfig()); + modules.add(new KeystoneJdbcModule()); + modules.add(new KeystoneOpsSystemModule()); + modules.add(new CodahaleMetricsModule()); + modules.add(new JerseyServletModule() { + @Override + protected void configureServlets() { + bind(TokensResource.class); + bind(KeychainResource.class); + bind(PkiResource.class); + bind(ServicesResource.class); - public void start(int port) throws Exception { - this.server = new Server(port); + Map params = Maps.newHashMap(); + params.put(PackagesResourceConfig.PROPERTY_PACKAGES, + "org.openstack.keystone.jaxrs;org.codehaus.jackson.jaxrs"); + serve("/*").with(GuiceContainer.class, params); + } + }); - ServletContextHandler context = new ServletContextHandler(); - context.setContextPath("/"); - server.setHandler(context); + Injector injector = Guice.createInjector(modules); - context.addEventListener(new AdminServerConfig()); + KeystoneAdminServer server = injector.getInstance(KeystoneAdminServer.class); + server.start(WellKnownPorts.PORT_PLATFORMLAYER_AUTH_ADMIN); + } - // Must add DefaultServlet for embedded Jetty - // Failing to do this will cause 404 errors. - context.addServlet(DefaultServlet.class, "/"); + public void start(int port) throws Exception { + EnumSet options = EnumSet.of(SslOption.AllowAnyClientCertificate, SslOption.WantClientCertificate); - FilterHolder filterHolder = new FilterHolder(GuiceFilter.class); - context.addFilter(filterHolder, "*", EnumSet.of(DispatcherType.REQUEST)); + serverBuilder.addHttpsConnector(port, options); + serverBuilder.addGuiceContext("/", injector); - context.setClassLoader(Thread.currentThread().getContextClassLoader()); + this.jettyServer = serverBuilder.start(); - server.start(); + metricReporter.start(); } public void stop() throws Exception { - if (server != null) { - server.stop(); + if (jettyServer != null) { + jettyServer.stop(); } } } diff --git a/auth/server-admin/src/main/java/org/platformlayer/auth/FakeAuthServlet.java b/auth/server-admin/src/main/java/org/platformlayer/auth/FakeAuthServlet.java deleted file mode 100644 index 8be0bad81..000000000 --- a/auth/server-admin/src/main/java/org/platformlayer/auth/FakeAuthServlet.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.platformlayer.auth; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class FakeAuthServlet extends HttpServlet { - private static final long serialVersionUID = -8270345309937119194L; - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - // GET /v1.0 HTTP/1.1 - // Host: auth.api.rackspacecloud.com - // X-Auth-User: jdoe - // X-Auth-Key: a86850deb2742ec3cb41518e26aa2d89 - - String user = req.getHeader("X-Auth-User"); - String secret = req.getHeader("X-Auth-Key"); - - if (user != null && user.startsWith("USER-")) { - int userId = Integer.parseInt(user.substring(5)); - String correctSecret = "SECRET-" + userId; - if (correctSecret.equals(secret)) { - sendCorrectAuth(userId, resp); - return; - } - } - - // Return 401 unauthorized - resp.setStatus(401); - } - - void sendCorrectAuth(int userId, HttpServletResponse response) { - /* - * If authentication is successful, an HTTP status 204 No Content is returned with three cloud service headers, - * X-Server-Management-Url, X-Storage-Url, X-CDN-Management-Url, as well as X-Auth-Token - */ - - String xaasUrl = "http://127.0.0.1:8082/" + userId; - - String authToken = "DEV-TOKEN-" + userId; - response.setHeader("X-Auth-Token", authToken); - - response.setHeader("X-Server-Management-Url", ""); - response.setHeader("X-Storage-Url", ""); - response.setHeader("X-CDN-Management-Url", ""); - response.setHeader("X-PlatformLayer-Url", xaasUrl); - - response.setStatus(204); - } -} diff --git a/auth/server-admin/src/main/java/org/platformlayer/auth/StandaloneAuthServer.java b/auth/server-admin/src/main/java/org/platformlayer/auth/StandaloneAuthServer.java deleted file mode 100644 index 2504bb31b..000000000 --- a/auth/server-admin/src/main/java/org/platformlayer/auth/StandaloneAuthServer.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.platformlayer.auth; - -import java.io.File; - -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.ContextHandlerCollection; -import org.eclipse.jetty.webapp.WebAppContext; - -public class StandaloneAuthServer { - static final int PORT = 8081; - - private Server server; - - public static void main(String[] args) throws Exception { - System.setProperty("application.mode", "development"); - - StandaloneAuthServer server = new StandaloneAuthServer(); - server.start(); - - // try { - // while (true) { - // Thread.sleep(5000); - // } - // } finally { - // server.stop(); - // } - } - - public void start() throws Exception { - this.server = new Server(PORT); - ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection(); - - WebAppContext root = new WebAppContext(); - - File base = new File(".").getCanonicalFile(); - root.setWar(new File(base, "src/main/webapp").getCanonicalPath()); - root.setContextPath("/"); - contextHandlerCollection.addHandler(root); - - server.setHandler(contextHandlerCollection); - - server.start(); - - } - - public void stop() throws Exception { - if (server != null) { - server.stop(); - } - } - -} diff --git a/auth/server-admin/src/main/resources/log4j.properties b/auth/server-admin/src/main/resources/log4j.properties deleted file mode 100644 index 9e3571975..000000000 --- a/auth/server-admin/src/main/resources/log4j.properties +++ /dev/null @@ -1,8 +0,0 @@ -log4j.rootLogger=DEBUG, CONSOLE - -log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender -log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout -log4j.appender.CONSOLE.layout.ConversionPattern=%d [%t] %-5p %c - %m%n - -# Dial down logging on standard libraries -log4j.logger.org.eclipse.jetty=INFO diff --git a/auth/server-shared/pom.xml b/auth/server-shared/pom.xml index edd0d8f2f..aeeea8eb2 100644 --- a/auth/server-shared/pom.xml +++ b/auth/server-shared/pom.xml @@ -13,33 +13,48 @@ + - org.platformlayer - keystone-api - ${version.project} + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider - - + - org.codehaus.jackson - jackson-xc + com.yammer.metrics + metrics-annotation + - org.codehaus.jackson - jackson-jaxrs + com.yammer.metrics + metrics-jetty - + + + com.yammer.metrics + metrics-core + + + + + org.bouncycastle + bcprov-jdk15on + + + + org.bouncycastle + bcpkix-jdk15on + + org.eclipse.jetty jetty-webapp - ${jetty.version} org.eclipse.jetty jetty-server - ${jetty.version} @@ -48,35 +63,46 @@ platformlayer-auth - - org.slf4j - slf4j-log4j12 - - org.eclipse.jetty jetty-servlet - ${jetty.version} + com.google.inject guice - ${guice.verion} com.sun.jersey jersey-server - ${jersey.version} + + + com.sun.jersey + jersey-json com.sun.jersey.contribs jersey-guice - ${jersey.version} + + + com.fathomdb + fathomdb-ratelimit + + + + com.fathomdb + fathomdb-server + + + + com.fathomdb + fathomdb-jpa + + junit junit - ${junit.version} test @@ -86,63 +112,15 @@ - - org.codehaus.mojo jaxb2-maven-plugin - - - - generate-resources - - schemagen - - - + 1.5 - ${project.build.directory}/schemas - ${basedir} - src/main/java/org/openstack/keystone/model/**/*.java + **/model/**/*.java - true - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - com.sun.tools.jxc.maven2 - maven-jaxb-schemagen-plugin - [1.2,) - - generate - - - - - - - - - - - -
- - diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/jaxrs/JacksonConfigurator.java b/auth/server-shared/src/main/java/org/openstack/keystone/jaxrs/JacksonConfigurator.java deleted file mode 100644 index 37401e993..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/jaxrs/JacksonConfigurator.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.openstack.keystone.jaxrs; - -import java.text.SimpleDateFormat; -import java.util.TimeZone; - -import javax.ws.rs.Produces; -import javax.ws.rs.ext.ContextResolver; -import javax.ws.rs.ext.Provider; - -import org.codehaus.jackson.map.DeserializationConfig; -import org.codehaus.jackson.map.ObjectMapper; -import org.codehaus.jackson.map.SerializationConfig; - -@Provider -@Produces("application/json") -public class JacksonConfigurator implements ContextResolver { - - private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss"; - private ObjectMapper mapper = new ObjectMapper(); - - public JacksonConfigurator() { - SerializationConfig serConfig = mapper.getSerializationConfig(); - SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); - dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - - serConfig.setDateFormat(dateFormat); - - DeserializationConfig deserializationConfig = mapper.getDeserializationConfig(); - deserializationConfig.setDateFormat(dateFormat); - - mapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false); - } - - @Override - public ObjectMapper getContext(Class arg0) { - return mapper; - } - -} \ No newline at end of file diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/Access.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/Access.java deleted file mode 100644 index 2c561158b..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/Access.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.openstack.keystone.model; - -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement -@XmlAccessorType(XmlAccessType.FIELD) -public class Access { - public Token token; - - public List serviceCatalog; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/Auth.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/Auth.java deleted file mode 100644 index f8a37decf..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/Auth.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.openstack.keystone.model; - -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement -@XmlAccessorType(XmlAccessType.FIELD) -public class Auth { - public PasswordCredentials passwordCredentials; - - @XmlAttribute - public String tenantName; - - public Token token; - - public List serviceCatalog; - - @XmlElement(name = "user") - public UserValidation userValidation; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/AuthenticateRequest.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/AuthenticateRequest.java deleted file mode 100644 index 62118f047..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/AuthenticateRequest.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.openstack.keystone.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement -@XmlAccessorType(XmlAccessType.FIELD) -public class AuthenticateRequest { - public Auth auth; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/AuthenticateResponse.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/AuthenticateResponse.java deleted file mode 100644 index 5b1ba2d7d..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/AuthenticateResponse.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.openstack.keystone.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement -@XmlAccessorType(XmlAccessType.FIELD) -public class AuthenticateResponse { - public Access access; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/Ec2ConvertTokenRequest.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/Ec2ConvertTokenRequest.java deleted file mode 100644 index ee99a2885..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/Ec2ConvertTokenRequest.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.openstack.keystone.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement -@XmlAccessorType(XmlAccessType.FIELD) -public class Ec2ConvertTokenRequest { - public Ec2Credentials ec2Credentials; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/Ec2ConvertTokenResponse.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/Ec2ConvertTokenResponse.java deleted file mode 100644 index 4e8b286b3..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/Ec2ConvertTokenResponse.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.openstack.keystone.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement -@XmlAccessorType(XmlAccessType.FIELD) -public class Ec2ConvertTokenResponse { - public Ec2Credentials credentials; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/Ec2Credentials.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/Ec2Credentials.java deleted file mode 100644 index 31383fa4f..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/Ec2Credentials.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.openstack.keystone.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - -@XmlAccessorType(XmlAccessType.FIELD) -public class Ec2Credentials { - public String access; - public String signature; - public String host; - public String verb; - public String path; - public Ec2RequestParameters params; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/Ec2RequestParameters.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/Ec2RequestParameters.java deleted file mode 100644 index 4cbdd7e00..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/Ec2RequestParameters.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.openstack.keystone.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - -@XmlAccessorType(XmlAccessType.FIELD) -public class Ec2RequestParameters { - -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/PasswordCredentials.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/PasswordCredentials.java deleted file mode 100644 index aced7b1ac..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/PasswordCredentials.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.openstack.keystone.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - -@XmlAccessorType(XmlAccessType.FIELD) -public class PasswordCredentials { - public String username; - public String password; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/Role.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/Role.java deleted file mode 100644 index c197959a7..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/Role.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.openstack.keystone.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - -@XmlAccessorType(XmlAccessType.FIELD) -public class Role { - public String name; - - public String tenantId; - - public String description; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/RoleList.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/RoleList.java deleted file mode 100644 index 41c0b338a..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/RoleList.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.openstack.keystone.model; - -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement(name = "roles") -@XmlAccessorType(XmlAccessType.FIELD) -public class RoleList { - @XmlElement(name = "role") - public List roles; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/Service.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/Service.java deleted file mode 100644 index d33278065..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/Service.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.openstack.keystone.model; - -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement -@XmlAccessorType(XmlAccessType.FIELD) -public class Service { - public String type; - - public String name; - - public List endpoints; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/ServiceEndpoint.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/ServiceEndpoint.java deleted file mode 100644 index d4b02c10b..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/ServiceEndpoint.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.openstack.keystone.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - -@XmlAccessorType(XmlAccessType.FIELD) -public class ServiceEndpoint { - public String region; - - public String tenantId; - - public String internalURL; - - public String publicURL; - - public ServiceVersion version; - - @Override - public String toString() { - return "ServiceEndpoint [region=" + region + ", tenantId=" + tenantId + ", internalURL=" + internalURL - + ", publicURL=" + publicURL + ", version=" + version + "]"; - } -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/ServiceVersion.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/ServiceVersion.java deleted file mode 100644 index 326bb0e0e..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/ServiceVersion.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.openstack.keystone.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; - -@XmlAccessorType(XmlAccessType.FIELD) -public class ServiceVersion { - @XmlAttribute - public String id; - - @XmlAttribute - public String info; - - @XmlAttribute - public String list; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/Tenant.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/Tenant.java deleted file mode 100644 index 154f870a6..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/Tenant.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.openstack.keystone.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; - -@XmlAccessorType(XmlAccessType.FIELD) -public class Tenant { - @XmlAttribute - public boolean enabled; - - @XmlAttribute - public String id; - - @XmlAttribute - public String name; - - public String description; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/TenantEndpoint.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/TenantEndpoint.java deleted file mode 100644 index 874c632e3..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/TenantEndpoint.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.openstack.keystone.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; - -@XmlAccessorType(XmlAccessType.FIELD) -public class TenantEndpoint { - @XmlAttribute - public String href; - - @XmlAttribute - public String id; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/TenantEndpointList.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/TenantEndpointList.java deleted file mode 100644 index 5ec0e85fa..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/TenantEndpointList.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.openstack.keystone.model; - -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement(name = "tenants") -@XmlAccessorType(XmlAccessType.FIELD) -public class TenantEndpointList { - public List tenants; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/TenantsList.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/TenantsList.java deleted file mode 100644 index ea403ffbd..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/TenantsList.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.openstack.keystone.model; - -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement(name = "tenants") -@XmlAccessorType(XmlAccessType.FIELD) -public class TenantsList { - public List tenant; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/Token.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/Token.java deleted file mode 100644 index 4adab92c5..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/Token.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.openstack.keystone.model; - -import java.util.Date; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - -@XmlAccessorType(XmlAccessType.FIELD) -public class Token { - public Date expires; - public String id; - public Tenant tenant; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/User.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/User.java deleted file mode 100644 index 3b41eb50a..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/User.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.openstack.keystone.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement(name = "user") -@XmlAccessorType(XmlAccessType.FIELD) -public class User { - @XmlAttribute - public boolean enabled; - - @XmlAttribute - public String email; - - public String username; - - @XmlAttribute - public String id; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/UserValidation.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/UserValidation.java deleted file mode 100644 index 075a23f09..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/UserValidation.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.openstack.keystone.model; - -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - -@XmlAccessorType(XmlAccessType.FIELD) -public class UserValidation { - public String id; - public String name; - - public byte[] secret; - - public List roles; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/ValidateAccess.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/ValidateAccess.java deleted file mode 100644 index d6e411344..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/ValidateAccess.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.openstack.keystone.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement -@XmlAccessorType(XmlAccessType.FIELD) -public class ValidateAccess { - public Token token; - - public UserValidation user; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/ValidateTokenResponse.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/ValidateTokenResponse.java deleted file mode 100644 index 6a71fc240..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/ValidateTokenResponse.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.openstack.keystone.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement -@XmlAccessorType(XmlAccessType.FIELD) -public class ValidateTokenResponse { - public ValidateAccess access; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/model/package-info.java b/auth/server-shared/src/main/java/org/openstack/keystone/model/package-info.java deleted file mode 100644 index b4265e263..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/model/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -@javax.xml.bind.annotation.XmlSchema(namespace = "http://docs.openstack.org/identity/api/v2.0", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) -package org.openstack.keystone.model; - diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/resources/KeystoneResourceBase.java b/auth/server-shared/src/main/java/org/openstack/keystone/resources/KeystoneResourceBase.java deleted file mode 100644 index 993b3a4d3..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/resources/KeystoneResourceBase.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.openstack.keystone.resources; - -import java.util.Date; -import java.util.List; - -import javax.inject.Inject; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.HttpHeaders; - -import org.apache.log4j.Logger; -import org.openstack.keystone.model.Auth; -import org.openstack.keystone.services.AuthenticationFacade; -import org.openstack.keystone.services.AuthenticationInfo; -import org.openstack.keystone.services.AuthenticatorException; -import org.openstack.keystone.services.TokenInfo; -import org.platformlayer.TimeSpan; - -public class KeystoneResourceBase { - static final Logger log = Logger.getLogger(KeystoneResourceBase.class); - - protected static final String AUTH_HEADER = "X-Auth-Token"; - protected static final TimeSpan TOKEN_VALIDITY = new TimeSpan("1h"); - - public static final String APPLICATION_JSON = javax.ws.rs.core.MediaType.APPLICATION_JSON; - public static final String APPLICATION_XML = javax.ws.rs.core.MediaType.APPLICATION_XML; - - @Inject - protected AuthenticationFacade authentication; - - @Context - HttpHeaders httpHeaders; - - protected void throw404NotFound() { - throw new WebApplicationException(404); - } - - protected void throwUnauthorized() { - throw new WebApplicationException(401); - } - - protected void throwInternalError() { - throw new WebApplicationException(500); - } - - protected String getAuthHeader() { - List authHeader = httpHeaders.getRequestHeader(AUTH_HEADER); - if (authHeader == null || authHeader.isEmpty()) { - return null; - } - return authHeader.get(0); - } - - protected TokenInfo requireSystemToken() { - String authHeader = getAuthHeader(); - - TokenInfo myTokenInfo = authentication.validateToken(true, authHeader); - if (myTokenInfo == null || !myTokenInfo.isSystem()) { - throwUnauthorized(); - } - - return myTokenInfo; - } - - protected boolean isNullOrEmpty(List list) { - return (list == null) || (list.isEmpty()); - } - - protected TokenInfo tryAuthenticate(boolean isSystem, Auth request) throws AuthenticatorException { - String username = null; - String password = null; - String scope = request.tenantName; - - if (request.passwordCredentials != null) { - username = request.passwordCredentials.username; - password = request.passwordCredentials.password; - } - - AuthenticationInfo authenticated = authentication.authenticate(isSystem, username, password); - if (authenticated == null) { - log.debug("Authentication request failed for " + username); - - return null; - } - - return buildToken(isSystem, scope, authenticated.getUserId(), authenticated.getTokenSecret()); - } - - private TokenInfo buildToken(boolean isSystem, String scope, String userId, byte[] tokenSecret) { - Date now = new Date(); - Date expiration = TOKEN_VALIDITY.addTo(now); - - byte flags = 0; - if (isSystem) { - flags |= TokenInfo.FLAG_SYSTEM; - } - TokenInfo tokenInfo = new TokenInfo(flags, scope, userId, expiration, tokenSecret); - - return tokenInfo; - } -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/resources/Mapping.java b/auth/server-shared/src/main/java/org/openstack/keystone/resources/Mapping.java deleted file mode 100644 index 931f7c2eb..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/resources/Mapping.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.openstack.keystone.resources; - -import java.util.List; - -import org.openstack.keystone.model.Role; -import org.openstack.keystone.model.RoleList; -import org.openstack.keystone.model.Tenant; -import org.openstack.keystone.model.Token; -import org.openstack.keystone.model.User; -import org.openstack.keystone.services.TokenInfo; -import org.openstack.keystone.services.UserInfo; - -public class Mapping { - - public static Token mapToResponse(TokenInfo tokenInfo) { - Token token = new Token(); - token.expires = tokenInfo.expiration; - if (tokenInfo.scope != null) { - token.tenant = mapToTenant(tokenInfo); - } - - return token; - } - - private static Tenant mapToTenant(TokenInfo tokenInfo) { - Tenant tenant = new Tenant(); - tenant.id = tokenInfo.scope; - tenant.name = tokenInfo.scope; - return tenant; - } - - public static RoleList mapToRoles(List roles) { - RoleList roleList = new RoleList(); - roleList.roles = roles; - return roleList; - } - - public static User mapToUser(UserInfo userInfo) { - User user = new User(); - user.enabled = true; - user.id = userInfo.userId; - user.username = userInfo.username; - user.email = userInfo.email; - return user; - } - -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/server/GuiceAuthenticationConfig.java b/auth/server-shared/src/main/java/org/openstack/keystone/server/GuiceAuthenticationConfig.java deleted file mode 100644 index 0bbe96cd4..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/server/GuiceAuthenticationConfig.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.openstack.keystone.server; - -import java.io.File; -import java.io.IOException; -import java.util.Properties; - -import org.openstack.keystone.services.CacheSystem; -import org.openstack.keystone.services.GroupToTenantMapper; -import org.openstack.keystone.services.ServiceDictionary; -import org.openstack.keystone.services.TokenService; -import org.openstack.keystone.services.crypto.SharedSecretTokenService; -import org.openstack.keystone.services.memory.SimpleCacheSystem; -import org.openstack.keystone.services.memory.SimpleGroupToTenantMapper; -import org.openstack.keystone.services.memory.SimpleServiceDictionary; -import org.openstack.utils.PropertyUtils; - -import com.google.inject.AbstractModule; -import com.google.inject.Module; -import com.google.inject.name.Names; - -public class GuiceAuthenticationConfig extends AbstractModule { - - @Override - protected void configure() { - String configFilePath = System.getProperty("conf"); - if (configFilePath == null) { - configFilePath = new File(new File("."), "configuration.properties").getAbsolutePath(); - } - - File configFile = new File(configFilePath); - File baseDir = configFile.getParentFile(); - Properties config; - - try { - config = PropertyUtils.loadProperties(configFile); - } catch (IOException e) { - throw new IllegalStateException("Error loading configuration file: " + configFilePath, e); - } - - String secret = config.getProperty("sharedsecret"); - if (secret == null) { - throw new IllegalStateException("sharedsecret is required"); - } - - Names.bindProperties(binder(), config); - - bindAuthenticationModules(config); - - File serviceDirectory = new File(baseDir, "services"); - if (serviceDirectory.exists()) { - SimpleServiceDictionary serviceDictionary = SimpleServiceDictionary.loadFromDirectory(serviceDirectory); - - bind(ServiceDictionary.class).toInstance(serviceDictionary); - } - - TokenService tokenService = new SharedSecretTokenService(secret); - bind(TokenService.class).toInstance(tokenService); - - int cacheSize = 1000; - CacheSystem simpleCacheSystem = new SimpleCacheSystem(cacheSize); - bind(CacheSystem.class).toInstance(simpleCacheSystem); - - GroupToTenantMapper groupToTenantMapper = new SimpleGroupToTenantMapper(); - bind(GroupToTenantMapper.class).toInstance(groupToTenantMapper); - } - - private void bindAuthenticationModules(Properties config) { - String userProvider = config.getProperty("auth.user.module"); - if (userProvider != null) { - installModule(userProvider); - } - String systemProvider = config.getProperty("auth.system.module"); - if (systemProvider != null) { - installModule(systemProvider); - } - } - - private void installModule(String moduleClassName) { - try { - Class moduleClass = Class.forName(moduleClassName); - Module module = (Module) moduleClass.newInstance(); - binder().install(module); - } catch (Exception e) { - throw new IllegalStateException("Error loading class: " + moduleClassName); - } - } - -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/services/AuthenticationFacade.java b/auth/server-shared/src/main/java/org/openstack/keystone/services/AuthenticationFacade.java deleted file mode 100644 index e6ead1c99..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/services/AuthenticationFacade.java +++ /dev/null @@ -1,127 +0,0 @@ -package org.openstack.keystone.services; - -import java.util.Collection; -import java.util.Date; -import java.util.List; - -import javax.inject.Inject; - -import org.apache.log4j.Logger; -import org.openstack.keystone.model.Role; -import org.platformlayer.ApplicationMode; -import org.platformlayer.TimeSpan; - -import com.google.common.base.Objects; -import com.google.common.collect.Lists; - -public class AuthenticationFacade { - static final Logger log = Logger.getLogger(AuthenticationFacade.class); - - private static final TimeSpan CACHE_USERINFO = TimeSpan.FIVE_MINUTES; - - @Inject - UserAuthenticator userAuthenticator; - - @Inject - SystemAuthenticator systemAuthenticator; - - @Inject - TokenService tokenService; - - @Inject - GroupToTenantMapper groupToTenantMapper; - - @Inject - CacheSystem cache; - - public List getRoles(UserInfo userInfo, String filterTenantId) { - Collection groups = userInfo.groups; - List roles = Lists.newArrayList(); - for (String group : groups) { - TenantInfo tenantInfo = groupToTenantMapper.mapGroupToTenant(group); - if (tenantInfo != null) { - if (filterTenantId != null && !Objects.equal(filterTenantId, tenantInfo.tenantId)) { - continue; - } - - Role role = new Role(); - role.description = tenantInfo.roleId; - role.name = tenantInfo.roleId; - role.tenantId = tenantInfo.tenantId; - - roles.add(role); - } - } - - return roles; - } - - public AuthenticationInfo authenticate(boolean isSystem, String username, String password) - throws AuthenticatorException { - AuthenticationInfo userId; - if (isSystem) { - userId = systemAuthenticator.authenticate(username, password); - } else { - userId = userAuthenticator.authenticate(username, password); - } - if (userId == null) { - return null; - } - return userId; - } - - public UserInfo getUserInfo(boolean isSystem, String userId, byte[] tokenSecret) throws AuthenticatorException { - String key = (isSystem ? "sys:" : "user:") + userId; - UserInfo userInfo = cache.lookup(key, UserInfo.class); - if (userInfo == null) { - // Find groups - GenericAuthenticator authenticator = isSystem ? systemAuthenticator : userAuthenticator; - GroupResolver groupResolver = new GroupResolver(authenticator.getGroupMembership()); - Collection groups = groupResolver.findGroups(userId); - - // We assume username == userId (for now) - String username = userId; - - String email = null; - - byte[] userSecret = null; - if (tokenSecret != null) { - userSecret = authenticator.getUserSecret(userId, tokenSecret); - } - - userInfo = new UserInfo(userId, username, email, userSecret, groups); - cache.put(key, CACHE_USERINFO, userInfo); - } - return userInfo; - } - - public TokenInfo validateToken(boolean system, String token) { - if (ApplicationMode.isDevelopment()) { - if (system && token.equals("auth_token")) { - byte flags = TokenInfo.FLAG_SYSTEM; - String scope = null; - String userId = "system"; - Date expiration = null; - byte[] tokenSecret = null; - TokenInfo tokenInfo = new TokenInfo(flags, scope, userId, expiration, tokenSecret); - return tokenInfo; - } - } - TokenInfo tokenInfo = tokenService.decodeToken(system, token); - if (tokenInfo == null || tokenInfo.hasExpired()) { - return null; - } - return tokenInfo; - } - - public String signToken(TokenInfo token) { - return tokenService.encodeToken(token); - } - - // public UserInfo getUserInfoByUsername(boolean isSystem, String username) throws AuthenticatorException { - // // We assume userId == username (for now) - // String userId = username; - // return getUserInfo(isSystem, userId); - // } - -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/services/CacheSystem.java b/auth/server-shared/src/main/java/org/openstack/keystone/services/CacheSystem.java deleted file mode 100644 index 43a945250..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/services/CacheSystem.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.openstack.keystone.services; - -import java.io.Serializable; - -import org.platformlayer.TimeSpan; - -public interface CacheSystem { - T lookup(String key, Class clazz); - - void put(String key, TimeSpan validity, Serializable value); -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/services/GroupResolver.java b/auth/server-shared/src/main/java/org/openstack/keystone/services/GroupResolver.java deleted file mode 100644 index f46c041b4..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/services/GroupResolver.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.openstack.keystone.services; - -import java.util.Collection; -import java.util.List; -import java.util.Set; - -import org.apache.log4j.Logger; - -import com.google.common.collect.Sets; - -public class GroupResolver { - // Prevent infinite recursion if we have a pathological structure - private static final int MAX_DEPTH = 128; - - static final Logger log = Logger.getLogger(GroupResolver.class); - - Set foundGroups = Sets.newHashSet(); - - final GroupMembershipOracle groupMembership; - - public GroupResolver(GroupMembershipOracle groupMembership) { - this.groupMembership = groupMembership; - } - - public Collection findGroups(String userId) throws AuthenticatorException { - visit(userId, 0); - - return foundGroups; - } - - void visit(String entity, int depth) throws AuthenticatorException { - if (depth == 0) { - // Don't add the first entity; it's a user - } else { - if (depth >= MAX_DEPTH) { - log.warn("Max recursion depth encountered; won't descend further"); - return; - } - } - - List groups = groupMembership.getGroups(entity, depth != 0); - for (String group : groups) { - if (foundGroups.contains(group)) { - // Already visited - continue; - } else { - foundGroups.add(group); - visit(group, depth + 1); - } - } - } -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/services/GroupToTenantMapper.java b/auth/server-shared/src/main/java/org/openstack/keystone/services/GroupToTenantMapper.java deleted file mode 100644 index 98647dfd3..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/services/GroupToTenantMapper.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.openstack.keystone.services; - -public interface GroupToTenantMapper { - TenantInfo mapGroupToTenant(String groupId); -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/services/ServiceDictionary.java b/auth/server-shared/src/main/java/org/openstack/keystone/services/ServiceDictionary.java deleted file mode 100644 index da4a4594b..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/services/ServiceDictionary.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.openstack.keystone.services; - -import org.openstack.keystone.model.Service; - -public interface ServiceDictionary { - Service getServiceInfo(String serviceKey, String tenantId); -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/services/TenantInfo.java b/auth/server-shared/src/main/java/org/openstack/keystone/services/TenantInfo.java deleted file mode 100644 index d7e064bcd..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/services/TenantInfo.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.openstack.keystone.services; - -public class TenantInfo { - public String serviceKey; - public String tenantId; - public String roleId; -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/services/TokenInfo.java b/auth/server-shared/src/main/java/org/openstack/keystone/services/TokenInfo.java deleted file mode 100644 index 4a60e0823..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/services/TokenInfo.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.openstack.keystone.services; - -import java.util.Date; - -public class TokenInfo { - public final byte flags; - public final String scope; - public final String userId; - public final Date expiration; - public final byte[] tokenSecret; - - public static final byte FLAG_SYSTEM = 0x1; - - public TokenInfo(byte flags, String scope, String userId, Date expiration, byte[] tokenSecret) { - this.flags = flags; - this.scope = scope; - this.userId = userId; - this.expiration = expiration; - this.tokenSecret = tokenSecret; - } - - public boolean isSystem() { - return (flags & FLAG_SYSTEM) != 0; - } - - public boolean hasExpired() { - return expiration.getTime() < System.currentTimeMillis(); - } - -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/services/TokenService.java b/auth/server-shared/src/main/java/org/openstack/keystone/services/TokenService.java deleted file mode 100644 index f975edf63..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/services/TokenService.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.openstack.keystone.services; - -public interface TokenService { - TokenInfo decodeToken(boolean system, String token); - - String encodeToken(TokenInfo token); -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/services/UserInfo.java b/auth/server-shared/src/main/java/org/openstack/keystone/services/UserInfo.java deleted file mode 100644 index 282d902f7..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/services/UserInfo.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.openstack.keystone.services; - -import java.io.Serializable; -import java.util.Collection; - -public class UserInfo implements Serializable { - private static final long serialVersionUID = 1L; - - public final String userId; - public final String username; - public final Collection groups; - public final String email; - public final byte[] secret; - - public UserInfo(String userId, String username, String email, byte[] secret, Collection groups) { - this.userId = userId; - this.username = username; - this.email = email; - this.secret = secret; - this.groups = groups; - } - -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/services/crypto/SharedSecretTokenService.java b/auth/server-shared/src/main/java/org/openstack/keystone/services/crypto/SharedSecretTokenService.java deleted file mode 100644 index 9b3b1d22b..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/services/crypto/SharedSecretTokenService.java +++ /dev/null @@ -1,176 +0,0 @@ -package org.openstack.keystone.services.crypto; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Date; - -import javax.crypto.spec.SecretKeySpec; - -import org.openstack.keystone.services.TokenInfo; -import org.openstack.keystone.services.TokenService; -import org.openstack.utils.Utf8; -import org.platformlayer.IoUtils; -import org.platformlayer.crypto.CryptoUtils; -import org.platformlayer.crypto.SecureComparison; - -public class SharedSecretTokenService implements TokenService { - private final SecretKeySpec systemSecretKeySpec; - private final SecretKeySpec userSecretKeySpec; - - // To keep the numbers smaller; we quantize time and offset it - static final long TIME_GRANULARITY = 60000L; - static final long TIME_OFFSET = 1234567890; - - public SharedSecretTokenService(String secret) { - // TODO: Use different keys - this.systemSecretKeySpec = CryptoUtils.deriveHmacSha1Key(secret); - this.userSecretKeySpec = CryptoUtils.deriveHmacSha1Key(secret); - } - - @Override - public TokenInfo decodeToken(boolean system, String token) { - if (token == null) { - return null; - } - - try { - String base64 = unescapeBase64(token); - byte[] buffer = CryptoUtils.fromBase64(base64); - - ByteArrayInputStream bais = new ByteArrayInputStream(buffer); - byte flags = (byte) bais.read(); - if (flags == -1) { - return null; - } - - String scope = readNullTerminatedString(bais); - if (scope.length() == 0) { - scope = null; - } - - String expiration = readNullTerminatedString(bais); - String username = readNullTerminatedString(bais); - byte[] tokenSecret = readLengthPrefixByteArray(bais); - - byte[] signature = new byte[CryptoUtils.HMAC_SHA1_BYTES]; - if (bais.read(signature) != CryptoUtils.HMAC_SHA1_BYTES) { - return null; - } - - SecretKeySpec secretKeySpec = system ? systemSecretKeySpec : userSecretKeySpec; - byte[] actualSignature = CryptoUtils.hmacSha1(secretKeySpec, buffer, 0, buffer.length - - CryptoUtils.HMAC_SHA1_BYTES); - - if (!SecureComparison.equal(actualSignature, signature)) { - return null; - } - - long roundedTime = Long.parseLong(expiration, 16); - long time = (roundedTime * TIME_GRANULARITY) + TIME_OFFSET; - - return new TokenInfo(flags, scope, username, new Date(time), tokenSecret); - } catch (Exception e) { - return null; - } - } - - private static String readNullTerminatedString(InputStream is) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - while (true) { - int nextByte = is.read(); - if (nextByte == -1) { - break; - } - if (nextByte == 0) { - break; - } - baos.write(nextByte); - } - - return Utf8.toString(baos); - } - - private static byte[] readLengthPrefixByteArray(InputStream is) throws IOException { - int length = is.read(); - if (length == -1) { - throw new EOFException(); - } - - if (length == 0) { - return null; - } - - length--; - - byte[] data = new byte[length]; - IoUtils.readFully(is, data, 0, length); - return data; - } - - @Override - public String encodeToken(TokenInfo tokenInfo) { - long time = tokenInfo.expiration.getTime(); - - long roundedTime = ((time - TIME_OFFSET) + TIME_GRANULARITY - 1) / TIME_GRANULARITY; - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - baos.write(tokenInfo.flags); - if (tokenInfo.scope != null) { - baos.write(Utf8.getBytes(tokenInfo.scope)); - } - baos.write(0); - baos.write(Utf8.getBytes(Long.toHexString(roundedTime))); - baos.write(0); - baos.write(Utf8.getBytes(tokenInfo.userId)); - baos.write(0); - if (tokenInfo.tokenSecret != null) { - if (tokenInfo.tokenSecret.length >= 100) { - // We might want to use a variable length integer encoding in future - throw new IllegalStateException(); - } - baos.write(tokenInfo.tokenSecret.length + 1); - baos.write(tokenInfo.tokenSecret); - } else { - baos.write(0); - } - } catch (IOException e) { - throw new IllegalStateException(); - } - - SecretKeySpec secretKeySpec = tokenInfo.isSystem() ? systemSecretKeySpec : userSecretKeySpec; - byte[] signed = CryptoUtils.hmacSha1(secretKeySpec, baos.toByteArray()); - if (signed.length != CryptoUtils.HMAC_SHA1_BYTES) { - throw new IllegalStateException(); - } - - try { - baos.write(signed); - } catch (IOException e) { - throw new IllegalStateException(); - } - - String base64 = CryptoUtils.toBase64(baos.toByteArray()); - String encoded = escapeBase64(base64); - - return encoded; - } - - static String escapeBase64(String s) { - s = s.replace('+', '_'); - s = s.replace('/', '.'); - s = s.replace('=', '-'); - return s; - } - - static String unescapeBase64(String s) { - s = s.replace('_', '+'); - s = s.replace('.', '/'); - s = s.replace('-', '='); - return s; - } - -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/services/ldap/LdapAuthentication.java b/auth/server-shared/src/main/java/org/openstack/keystone/services/ldap/LdapAuthentication.java deleted file mode 100644 index 0dcaf02d0..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/services/ldap/LdapAuthentication.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.openstack.keystone.services.ldap; - -//package org.platformlayer.keystone.services; -// -//import java.util.Hashtable; -// -//import javax.naming.Context; -//import javax.naming.ldap.InitialLdapContext; -//import javax.naming.ldap.LdapContext; -// -//public class LdapAuthentication { -// public void test() { -// Hashtable env = new Hashtable(); -// env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); -// env.put(Context.PROVIDER_URL, "ldap://ourldap.warwick.ac.uk"); -// env.put("com.sun.jndi.ldap.connect.pool", "true"); -// -// LdapContext ctx = new InitialLdapContext(env, null); -// // do something useful with ctx -// ctx.close(); -// } -// -// // -// // -// // -// // -// // -// // never -// // 5000 -// // 3 -// // true -// // -// // -// // -// } diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/services/ldap/LdapGroupToTenantMapper.java b/auth/server-shared/src/main/java/org/openstack/keystone/services/ldap/LdapGroupToTenantMapper.java deleted file mode 100644 index 164313aae..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/services/ldap/LdapGroupToTenantMapper.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.openstack.keystone.services.ldap; - -import java.util.List; - -import org.openstack.keystone.services.GroupToTenantMapper; -import org.openstack.keystone.services.TenantInfo; - -import com.google.common.collect.Lists; - -public class LdapGroupToTenantMapper implements GroupToTenantMapper { - static class LdapMapping { - String groupSuffix; - String serviceKey; - } - - final List ldapMappings = Lists.newArrayList(); - - @Override - public TenantInfo mapGroupToTenant(String groupId) { - for (LdapMapping ldapMapping : ldapMappings) { - if (!groupId.endsWith(ldapMapping.groupSuffix)) { - continue; - } - - // We expect the group to be called something like: - // dn=Project1 Read, cn=Nova, cn=openstack, cn=org - - // ,cn=Nova,cn=openstack,cn=org is the suffix, and determines the service key - - String prefix = groupId.substring(0, groupId.length() - ldapMapping.groupSuffix.length()); - - // The prefix is e.g. "dn=Project1 Read" - - // For now, we simply assume this format... - int equalsIndex = prefix.indexOf("="); - if (equalsIndex == -1) { - continue; - } - String[] components = prefix.substring(equalsIndex + 1).split(" "); - if (components.length != 2) { - continue; - } - - TenantInfo tenantInfo = new TenantInfo(); - tenantInfo.serviceKey = ldapMapping.serviceKey; - tenantInfo.tenantId = components[0]; - tenantInfo.roleId = components[1]; - - return tenantInfo; - } - - return null; - } - -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/services/memory/PropertiesBasedAuthenticator.java b/auth/server-shared/src/main/java/org/openstack/keystone/services/memory/PropertiesBasedAuthenticator.java deleted file mode 100644 index dad2a6d57..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/services/memory/PropertiesBasedAuthenticator.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.openstack.keystone.services.memory; - -import java.util.Properties; - -import org.openstack.keystone.services.AuthenticationInfo; -import org.openstack.keystone.services.GenericAuthenticator; -import org.openstack.keystone.services.GroupMembershipOracle; -import org.platformlayer.crypto.SecureComparison; - -public class PropertiesBasedAuthenticator implements GenericAuthenticator { - final Properties properties; - final GroupMembershipOracle groupMembership; - - public PropertiesBasedAuthenticator(Properties properties) { - super(); - this.properties = properties; - this.groupMembership = new PropertiesBasedGroupMembership(properties); - } - - @Override - public AuthenticationInfo authenticate(String username, String password) { - String prefix = username; - - String passwordProperty = properties.getProperty(prefix + ".password"); - if (passwordProperty == null) { - return null; - } - - if (passwordProperty.startsWith("md5:")) { - // We could easily support hashed passwords - throw new UnsupportedOperationException(); - } else { - if (!SecureComparison.equal(passwordProperty, password)) { - return null; - } - } - - String userId = username; - byte[] tokenSecret = null; - AuthenticationInfo authenticated = new AuthenticationInfo(userId, tokenSecret); - return authenticated; - } - - @Override - public GroupMembershipOracle getGroupMembership() { - return groupMembership; - } - - @Override - public byte[] getUserSecret(String userId, byte[] tokenSecret) { - return null; - } -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/services/memory/PropertiesBasedGroupMembership.java b/auth/server-shared/src/main/java/org/openstack/keystone/services/memory/PropertiesBasedGroupMembership.java deleted file mode 100644 index 0dd76af00..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/services/memory/PropertiesBasedGroupMembership.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.openstack.keystone.services.memory; - -import java.util.List; -import java.util.Properties; - -import org.openstack.keystone.services.GroupMembershipOracle; - -import com.google.common.collect.Lists; - -public class PropertiesBasedGroupMembership implements GroupMembershipOracle { - final Properties properties; - - public PropertiesBasedGroupMembership(Properties properties) { - super(); - this.properties = properties; - } - - @Override - public List getGroups(String key, boolean isGroup) { - String prefix; - - if (isGroup) { - prefix = "group." + key; - } else { - prefix = "user." + key; - } - - List groups = Lists.newArrayList(); - - String groupsString = properties.getProperty(prefix + ".groups"); - if (groupsString != null) { - for (String group : groupsString.split(",")) { - groups.add(group); - } - } - - return groups; - } -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/services/memory/SimpleGroupToTenantMapper.java b/auth/server-shared/src/main/java/org/openstack/keystone/services/memory/SimpleGroupToTenantMapper.java deleted file mode 100644 index eb942320e..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/services/memory/SimpleGroupToTenantMapper.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.openstack.keystone.services.memory; - -import org.openstack.keystone.services.GroupToTenantMapper; -import org.openstack.keystone.services.TenantInfo; - -public class SimpleGroupToTenantMapper implements GroupToTenantMapper { - - @Override - public TenantInfo mapGroupToTenant(String groupId) { - if (groupId == null) { - return null; - } - String[] components = groupId.split("\\."); - if (components.length == 3) { - TenantInfo tenantInfo = new TenantInfo(); - tenantInfo.serviceKey = components[0]; - tenantInfo.tenantId = components[1]; - tenantInfo.roleId = components[2]; - - // if (Objects.equal("*", tenantInfo.tenantId)) { - // tenantInfo.tenantId = null; - // } - - return tenantInfo; - } - - if (components.length == 1) { - TenantInfo tenantInfo = new TenantInfo(); - tenantInfo.serviceKey = "platformlayer"; - tenantInfo.tenantId = components[0]; - tenantInfo.roleId = "admin"; - - return tenantInfo; - } - - return null; - } - -} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/services/memory/SimpleServiceDictionary.java b/auth/server-shared/src/main/java/org/openstack/keystone/services/memory/SimpleServiceDictionary.java deleted file mode 100644 index 84f098590..000000000 --- a/auth/server-shared/src/main/java/org/openstack/keystone/services/memory/SimpleServiceDictionary.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.openstack.keystone.services.memory; - -import java.io.File; -import java.io.FileInputStream; -import java.util.List; -import java.util.Map; - -import org.openstack.keystone.model.Service; -import org.openstack.keystone.model.ServiceEndpoint; -import org.openstack.keystone.model.ServiceVersion; -import org.openstack.keystone.services.ServiceDictionary; -import org.platformlayer.IoUtils; -import org.platformlayer.xml.JsonHelper; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -public class SimpleServiceDictionary implements ServiceDictionary { - final Map services = Maps.newHashMap(); - - public void addService(String serviceKey, Service serviceTemplate) { - services.put(serviceKey, serviceTemplate); - } - - @Override - public Service getServiceInfo(String serviceKey, String tenantId) { - Service service = services.get(serviceKey); - if (service == null) { - return null; - } - - return cloneAndReplace(service, tenantId); - } - - private Service cloneAndReplace(Service service, String tenantId) { - Service clone = new Service(); - clone.endpoints = cloneAndReplace(service.endpoints, tenantId); - clone.name = cloneAndReplace(service.name, tenantId); - clone.type = cloneAndReplace(service.type, tenantId); - return clone; - } - - private List cloneAndReplace(List endpoints, String tenantId) { - if (endpoints == null) { - return null; - } - List clone = Lists.newArrayList(); - for (ServiceEndpoint endpoint : endpoints) { - clone.add(cloneAndReplace(endpoint, tenantId)); - } - return clone; - } - - private ServiceEndpoint cloneAndReplace(ServiceEndpoint endpoint, String tenantId) { - ServiceEndpoint clone = new ServiceEndpoint(); - clone.region = cloneAndReplace(endpoint.region, tenantId); - clone.tenantId = cloneAndReplace(endpoint.tenantId, tenantId); - clone.internalURL = cloneAndReplace(endpoint.internalURL, tenantId); - clone.publicURL = cloneAndReplace(endpoint.publicURL, tenantId); - clone.version = cloneAndReplace(endpoint.version, tenantId); - - return clone; - } - - private ServiceVersion cloneAndReplace(ServiceVersion version, String tenantId) { - if (version == null) { - return null; - } - - ServiceVersion clone = new ServiceVersion(); - clone.id = cloneAndReplace(version.id, tenantId); - clone.info = cloneAndReplace(version.info, tenantId); - clone.list = cloneAndReplace(version.list, tenantId); - - return clone; - - } - - private String cloneAndReplace(String s, String tenantId) { - if (s == null) { - return null; - } - - if (s.contains("{tenantId}")) { - s = s.replace("{tenantId}", tenantId); - } - - return s; - } - - public static SimpleServiceDictionary loadFromDirectory(File dir) { - // JaxbHelper jaxbHelper = JaxbHelper.get(Service.class); - JsonHelper json = JsonHelper.build(Service.class); - json.addDefaultNamespace(); - - SimpleServiceDictionary dictionary = new SimpleServiceDictionary(); - - for (File file : dir.listFiles()) { - String serviceKey = file.getName(); - - Service serviceTemplate; - try { - FileInputStream fis = new FileInputStream(file); - try { - serviceTemplate = json.unmarshal(fis); - // serviceTemplate = (Service) jaxbHelper.unmarshal(fis, Service.class); - } finally { - IoUtils.safeClose(fis); - } - } catch (Exception e) { - throw new IllegalArgumentException("Error loading file: " + file, e); - } - - dictionary.addService(serviceKey, serviceTemplate); - } - - return dictionary; - } -} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/FakeAuthServlet.java b/auth/server-shared/src/main/java/org/platformlayer/auth/FakeAuthServlet.java deleted file mode 100644 index 8be0bad81..000000000 --- a/auth/server-shared/src/main/java/org/platformlayer/auth/FakeAuthServlet.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.platformlayer.auth; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class FakeAuthServlet extends HttpServlet { - private static final long serialVersionUID = -8270345309937119194L; - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - // GET /v1.0 HTTP/1.1 - // Host: auth.api.rackspacecloud.com - // X-Auth-User: jdoe - // X-Auth-Key: a86850deb2742ec3cb41518e26aa2d89 - - String user = req.getHeader("X-Auth-User"); - String secret = req.getHeader("X-Auth-Key"); - - if (user != null && user.startsWith("USER-")) { - int userId = Integer.parseInt(user.substring(5)); - String correctSecret = "SECRET-" + userId; - if (correctSecret.equals(secret)) { - sendCorrectAuth(userId, resp); - return; - } - } - - // Return 401 unauthorized - resp.setStatus(401); - } - - void sendCorrectAuth(int userId, HttpServletResponse response) { - /* - * If authentication is successful, an HTTP status 204 No Content is returned with three cloud service headers, - * X-Server-Management-Url, X-Storage-Url, X-CDN-Management-Url, as well as X-Auth-Token - */ - - String xaasUrl = "http://127.0.0.1:8082/" + userId; - - String authToken = "DEV-TOKEN-" + userId; - response.setHeader("X-Auth-Token", authToken); - - response.setHeader("X-Server-Management-Url", ""); - response.setHeader("X-Storage-Url", ""); - response.setHeader("X-CDN-Management-Url", ""); - response.setHeader("X-PlatformLayer-Url", xaasUrl); - - response.setStatus(204); - } -} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/jaxrs/JacksonConfigurator.java b/auth/server-shared/src/main/java/org/platformlayer/auth/jaxrs/JacksonConfigurator.java new file mode 100644 index 000000000..5bb4068db --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/jaxrs/JacksonConfigurator.java @@ -0,0 +1,39 @@ +package org.platformlayer.auth.jaxrs; + +import java.text.SimpleDateFormat; +import java.util.TimeZone; + +import javax.ws.rs.Produces; +import javax.ws.rs.ext.ContextResolver; +import javax.ws.rs.ext.Provider; + +import org.codehaus.jackson.map.DeserializationConfig; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.SerializationConfig; + +@Provider +@Produces("application/json") +public class JacksonConfigurator implements ContextResolver { + + private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss"; + private ObjectMapper mapper = new ObjectMapper(); + + public JacksonConfigurator() { + SerializationConfig serConfig = mapper.getSerializationConfig(); + SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + + serConfig.setDateFormat(dateFormat); + + DeserializationConfig deserializationConfig = mapper.getDeserializationConfig(); + deserializationConfig.setDateFormat(dateFormat); + + mapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false); + } + + @Override + public ObjectMapper getContext(Class arg0) { + return mapper; + } + +} \ No newline at end of file diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/AuthenticationSecrets.java b/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/AuthenticationSecrets.java new file mode 100644 index 000000000..12c893a42 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/AuthenticationSecrets.java @@ -0,0 +1,13 @@ +package org.platformlayer.auth.keystone; + +import com.fathomdb.crypto.CryptoKey; +import com.google.inject.ImplementedBy; + +@ImplementedBy(SimpleAuthenticationSecrets.class) +public interface AuthenticationSecrets { + + CryptoKey decryptSecretFromToken(byte[] tokenSecret); + + byte[] buildToken(CryptoKey userSecret); + +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/ClientCertificateSystemAuthenticator.java b/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/ClientCertificateSystemAuthenticator.java new file mode 100644 index 000000000..d9c080224 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/ClientCertificateSystemAuthenticator.java @@ -0,0 +1,63 @@ +package org.platformlayer.auth.keystone; + +import javax.inject.Inject; + +import org.platformlayer.RepositoryException; +import org.platformlayer.auth.AuthenticatorException; +import org.platformlayer.auth.ServiceAccountEntity; +import org.platformlayer.auth.UserDatabase; +import org.platformlayer.auth.model.CertificateChainInfo; +import org.platformlayer.auth.model.CertificateInfo; +import org.platformlayer.auth.services.SystemAuthenticator; +import org.platformlayer.metrics.Instrumented; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fathomdb.utils.Hex; +import com.google.common.base.Strings; + +@Instrumented +public class ClientCertificateSystemAuthenticator implements SystemAuthenticator { + private static final Logger log = LoggerFactory.getLogger(ClientCertificateSystemAuthenticator.class); + + @Inject + UserDatabase repository; + + @Override + public ServiceAccountEntity authenticate(CertificateChainInfo certChainInfo) throws AuthenticatorException { + if (certChainInfo.certificates.size() == 0) { + log.debug("Chain empty; can't authenticate"); + return null; + } + + // If it's a single cert; we check the cert. + // Otherwise, we assume a CA signed the tail cert, so we check the penultimate cert + CertificateInfo inspect; + if (certChainInfo.certificates.size() == 1) { + inspect = certChainInfo.certificates.get(0); + } else { + inspect = certChainInfo.certificates.get(1); + } + + String subject = inspect.subjectDN; + if (Strings.isNullOrEmpty(inspect.publicKey)) { + throw new IllegalArgumentException(); + } + byte[] publicKey = Hex.fromHex(inspect.publicKey); + + ServiceAccountEntity auth; + try { + auth = repository.findServiceAccount(subject, publicKey); + } catch (RepositoryException e) { + throw new AuthenticatorException("Error while authenticating user", e); + } + + if (auth == null) { + log.debug("Certificate validation failed (though the caller was authenticated)"); + log.debug("Certificate validation failed - public key not recognized: " + Hex.toHex(publicKey)); + log.debug("Certificate validation failed - chain: " + certChainInfo); + } + + return auth; + } +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/KeystoneOpsSystemModule.java b/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/KeystoneOpsSystemModule.java new file mode 100644 index 000000000..6b17c35e4 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/KeystoneOpsSystemModule.java @@ -0,0 +1,19 @@ +package org.platformlayer.auth.keystone; + +import org.platformlayer.auth.JdbcUserRepository; +import org.platformlayer.auth.UserDatabase; +import org.platformlayer.auth.services.SystemAuthenticator; + +import com.google.inject.AbstractModule; + +public class KeystoneOpsSystemModule extends AbstractModule { + + @Override + protected void configure() { + bind(UserDatabase.class).to(JdbcUserRepository.class).asEagerSingleton(); + + bind(KeystoneUserAuthenticator.class).to(KeystoneRepositoryAuthenticator.class).asEagerSingleton(); + + bind(SystemAuthenticator.class).to(ClientCertificateSystemAuthenticator.class).asEagerSingleton(); + } +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/KeystoneOpsUserModule.java b/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/KeystoneOpsUserModule.java new file mode 100644 index 000000000..a88d00274 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/KeystoneOpsUserModule.java @@ -0,0 +1,20 @@ +package org.platformlayer.auth.keystone; + +import org.platformlayer.auth.JdbcUserRepository; +import org.platformlayer.auth.UserDatabase; +import org.platformlayer.inject.GuiceObjectInjector; +import org.platformlayer.inject.ObjectInjector; + +import com.google.inject.AbstractModule; + +public class KeystoneOpsUserModule extends AbstractModule { + + @Override + protected void configure() { + bind(ObjectInjector.class).to(GuiceObjectInjector.class); + + bind(UserDatabase.class).to(JdbcUserRepository.class).asEagerSingleton(); + + bind(KeystoneUserAuthenticator.class).to(KeystoneRepositoryAuthenticator.class).asEagerSingleton(); + } +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/KeystoneRepositoryAuthenticator.java b/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/KeystoneRepositoryAuthenticator.java new file mode 100644 index 000000000..adb23124b --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/KeystoneRepositoryAuthenticator.java @@ -0,0 +1,221 @@ +package org.platformlayer.auth.keystone; + +import java.util.List; + +import javax.inject.Inject; + +import org.platformlayer.RepositoryException; +import org.platformlayer.auth.AuthenticatorException; +import org.platformlayer.auth.CertificateAuthenticationRequest; +import org.platformlayer.auth.CertificateAuthenticationResponse; +import org.platformlayer.auth.ProjectEntity; +import org.platformlayer.auth.UserDatabase; +import org.platformlayer.auth.UserEntity; +import org.platformlayer.auth.UserProjectEntity; +import org.platformlayer.auth.model.CertificateChainInfo; +import org.platformlayer.metrics.Instrumented; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fathomdb.crypto.CryptoKey; +import com.fathomdb.utils.Hex; +import com.google.common.base.Strings; + +@Instrumented +public class KeystoneRepositoryAuthenticator implements KeystoneUserAuthenticator { + private static final Logger log = LoggerFactory.getLogger(KeystoneRepositoryAuthenticator.class); + + @Inject + UserDatabase repository; + + @Inject + AuthenticationSecrets authenticationSecrets; + + @Override + public UserEntity authenticate(String username, String password) throws AuthenticatorException { + if (username == null || password == null) { + return null; + } + + UserEntity user; + try { + user = (UserEntity) repository.authenticateWithPassword(username, password); + } catch (RepositoryException e) { + throw new AuthenticatorException("Error while authenticating user", e); + } + + if (user == null) { + return null; + } + + return user; + + // String userKey = "" + user.id; + // byte[] tokenSecret = user.getTokenSecret(); + // AuthenticationInfo authentication = new AuthenticationInfo(userKey, tokenSecret); + // return authentication; + } + + @Override + public CertificateAuthenticationResponse authenticate(CertificateAuthenticationRequest request) + throws AuthenticatorException { + try { + return repository.authenticateWithCertificate(request); + } catch (RepositoryException e) { + throw new AuthenticatorException("Error while authenticating user", e); + } + } + + // @Override + // public byte[] getUserSecret(String userIdString, byte[] tokenSecret) throws AuthenticatorException { + // int userId; + // try { + // userId = Integer.parseInt(userIdString); + // } catch (NumberFormatException e) { + // throw new AuthenticatorException("Invalid user id", e); + // } + // + // UserEntity user; + // try { + // user = (UserEntity) repository.findUserById(userId); + // } catch (RepositoryException e) { + // throw new AuthenticatorException("Error while authenticating user", e); + // } + // + // if (user != null) { + // user.unlockWithToken(UserEntity.TOKEN_ID_DEFAULT, tokenSecret); + // // TODO: Verify the item secret somehow?? + // } + // + // if (user == null) { + // throw new AuthenticatorException("User not found"); + // } + // + // SecretKey secretKey = user.getUserSecret(); + // if (secretKey != null) { + // return secretKey.getEncoded(); + // } + // return null; + // } + + // class SqlGroupMembershipOracle implements GroupMembershipOracle { + // @Override + // public List getGroups(String key, boolean isGroup) throws AuthenticatorException { + // if (!isGroup) { + // int userId = Integer.parseInt(key); + // List groups; + // try { + // groups = repository.listProjectsByUserId(userId); + // } catch (RepositoryException e) { + // throw new AuthenticatorException("Error while listing user groups", e); + // } + // List groupIds = Lists.newArrayList(); + // for (OpsProject group : groups) { + // groupIds.add(group.getName()); + // } + // return groupIds; + // } else { + // return Collections.emptyList(); + // } + // } + // + // }; + + // @Override + // public GroupMembershipOracle getGroupMembership() { + // return new SqlGroupMembershipOracle(); + // } + + @Override + public ProjectEntity findProject(String projectKey) throws AuthenticatorException { + ProjectEntity project; + try { + project = repository.findProjectByKey(projectKey); + } catch (RepositoryException e) { + throw new AuthenticatorException("Error while fetching project", e); + } + return project; + } + + @Override + public UserEntity getUserFromToken(String userIdString, byte[] tokenSecret) throws AuthenticatorException { + int userId; + try { + userId = Integer.parseInt(userIdString); + } catch (NumberFormatException e) { + throw new AuthenticatorException("Invalid user id", e); + } + + if (tokenSecret.length < 1) { + throw new IllegalArgumentException(); + } + + CryptoKey userSecret = authenticationSecrets.decryptSecretFromToken(tokenSecret); + if (userSecret == null) { + throw new AuthenticatorException("Authentication timed out"); + } + + UserEntity user; + try { + user = repository.findUserById(userId); + } catch (RepositoryException e) { + throw new AuthenticatorException("Error while authenticating user", e); + } + + user.unlock(userSecret); + + // user.unlockWithToken(UserEntity.TOKEN_ID_DEFAULT, tokenSecret); + + if (user.isLocked()) { + return null; + } + + return user; + } + + @Override + public UserEntity findUserFromKeychain(CertificateChainInfo chain, boolean unlock) throws AuthenticatorException { + if (chain.certificates == null || chain.certificates.isEmpty()) { + return null; + } + + for (int i = 0; i < chain.certificates.size(); i++) { + String publicKeyHash = chain.certificates.get(i).publicKeyHash; + if (Strings.isNullOrEmpty(publicKeyHash)) { + continue; + } + + log.debug("Checking publicKeyHash: " + publicKeyHash); + + byte[] hash = Hex.fromHex(publicKeyHash); + + UserEntity user; + try { + user = repository.findUserByPublicKey(hash); + } catch (RepositoryException e) { + throw new AuthenticatorException("Error while authenticating user", e); + } + + if (user != null) { + return user; + } + } + + return null; + } + + @Override + public List listProjects(UserEntity user) throws RepositoryException { + return repository.listProjectsByUserId(user.getId()); + } + + @Override + public UserProjectEntity findUserProject(UserEntity user, ProjectEntity project) throws AuthenticatorException { + try { + return repository.findUserProject(user.getId(), project.getId()); + } catch (RepositoryException e) { + throw new AuthenticatorException("Error while querying authentication store", e); + } + + } +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/KeystoneUserAuthenticator.java b/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/KeystoneUserAuthenticator.java new file mode 100644 index 000000000..ebace0040 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/KeystoneUserAuthenticator.java @@ -0,0 +1,29 @@ +package org.platformlayer.auth.keystone; + +import java.util.List; + +import org.platformlayer.RepositoryException; +import org.platformlayer.auth.AuthenticatorException; +import org.platformlayer.auth.CertificateAuthenticationRequest; +import org.platformlayer.auth.CertificateAuthenticationResponse; +import org.platformlayer.auth.ProjectEntity; +import org.platformlayer.auth.UserEntity; +import org.platformlayer.auth.UserProjectEntity; +import org.platformlayer.auth.model.CertificateChainInfo; + +public interface KeystoneUserAuthenticator { + UserEntity authenticate(String username, String password) throws AuthenticatorException; + + ProjectEntity findProject(String projectKey) throws AuthenticatorException; + + UserEntity getUserFromToken(String userId, byte[] tokenSecret) throws AuthenticatorException; + + CertificateAuthenticationResponse authenticate(CertificateAuthenticationRequest request) + throws AuthenticatorException; + + List listProjects(UserEntity user) throws RepositoryException; + + UserEntity findUserFromKeychain(CertificateChainInfo chain, boolean unlock) throws AuthenticatorException; + + UserProjectEntity findUserProject(UserEntity user, ProjectEntity project) throws AuthenticatorException; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/SimpleAuthenticationSecrets.java b/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/SimpleAuthenticationSecrets.java new file mode 100644 index 000000000..b67f8ccdd --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/keystone/SimpleAuthenticationSecrets.java @@ -0,0 +1,72 @@ +package org.platformlayer.auth.keystone; + +import java.util.Arrays; +import java.util.Map; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.platformlayer.crypto.CryptoUtils; + +import com.fathomdb.Configuration; +import com.fathomdb.crypto.CryptoKey; +import com.fathomdb.crypto.FathomdbCrypto; +import com.google.common.collect.Maps; +import com.google.common.primitives.Bytes; + +@Singleton +public class SimpleAuthenticationSecrets implements AuthenticationSecrets { + + final Map secrets = Maps.newHashMap(); + + byte currentTokenId; + + @Inject + public SimpleAuthenticationSecrets(Configuration configuration) { + this.currentTokenId = 1; + + String secret = configuration.find("sharedsecret"); + if (secret == null) { + throw new IllegalStateException("sharedsecret is required"); + } + + // This isn't ideal, but it needs to be consistent + byte[] salt = CryptoUtils.sha1(secret).toByteArray(); + + CryptoKey authSecret = FathomdbCrypto.deriveKeyRaw(1000, salt, secret); + secrets.put(this.currentTokenId, authSecret); + } + + @Override + public CryptoKey decryptSecretFromToken(byte[] tokenSecret) { + if (tokenSecret.length <= 2) { + return null; + } + + byte tokenId = tokenSecret[0]; + CryptoKey secret = secrets.get(tokenId); + if (secret == null) { + return null; + } + + byte[] ciphertext = Arrays.copyOfRange(tokenSecret, 1, tokenSecret.length); + byte[] plaintext = secret.decrypt(ciphertext); + return FathomdbCrypto.deserializeKey(plaintext); + } + + @Override + public byte[] buildToken(CryptoKey userSecret) { + byte tokenId = currentTokenId; + CryptoKey secret = secrets.get(tokenId); + if (secret == null) { + throw new IllegalStateException(); + } + + byte[] plaintext = FathomdbCrypto.serialize(userSecret); + byte[] ciphertext = secret.encrypt(plaintext); + + byte[] header = new byte[1]; + header[0] = tokenId; + return Bytes.concat(header, ciphertext); + } +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/Access.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/Access.java new file mode 100644 index 000000000..ef0c8b485 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/Access.java @@ -0,0 +1,17 @@ +package org.platformlayer.auth.model; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class Access { + public Token token; + + // public List serviceCatalog; + + public List projects; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/Auth.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/Auth.java new file mode 100644 index 000000000..c6bb2ee7c --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/Auth.java @@ -0,0 +1,22 @@ +package org.platformlayer.auth.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class Auth { + public PasswordCredentials passwordCredentials; + + public CertificateCredentials certificateCredentials; + + // @XmlAttribute + // public String project; + + public Token token; + + @XmlElement(name = "user") + public UserValidation userValidation; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/AuthenticateRequest.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/AuthenticateRequest.java new file mode 100644 index 000000000..71cb14282 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/AuthenticateRequest.java @@ -0,0 +1,11 @@ +package org.platformlayer.auth.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class AuthenticateRequest { + public Auth auth; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/AuthenticateResponse.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/AuthenticateResponse.java new file mode 100644 index 000000000..972c4094d --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/AuthenticateResponse.java @@ -0,0 +1,16 @@ +package org.platformlayer.auth.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class AuthenticateResponse { + public Access access; + + public byte[] challenge; + + // // For JSON-P + // public Integer statusCode; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/CertificateChainInfo.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/CertificateChainInfo.java new file mode 100644 index 000000000..c1af2e705 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/CertificateChainInfo.java @@ -0,0 +1,21 @@ +package org.platformlayer.auth.model; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +import com.google.common.collect.Lists; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class CertificateChainInfo { + public List certificates = Lists.newArrayList(); + + @Override + public String toString() { + return "CertificateChainInfo [certificates=" + certificates + "]"; + } + +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/CertificateCredentials.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/CertificateCredentials.java new file mode 100644 index 000000000..cf0e337fd --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/CertificateCredentials.java @@ -0,0 +1,11 @@ +package org.platformlayer.auth.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +@XmlAccessorType(XmlAccessType.FIELD) +public class CertificateCredentials { + public String username; + + public byte[] challengeResponse; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/CertificateInfo.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/CertificateInfo.java new file mode 100644 index 000000000..1e772319a --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/CertificateInfo.java @@ -0,0 +1,18 @@ +package org.platformlayer.auth.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +@XmlAccessorType(XmlAccessType.FIELD) +public class CertificateInfo { + public String publicKeyHash; + public String publicKey; + public String subjectDN; + + @Override + public String toString() { + return "CertificateInfo [subjectDN=" + subjectDN + ", publicKey=" + publicKey + ", publicKeyHash=" + + publicKeyHash + "]"; + } + +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/CheckServiceAccessRequest.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/CheckServiceAccessRequest.java new file mode 100644 index 000000000..9675033a5 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/CheckServiceAccessRequest.java @@ -0,0 +1,11 @@ +package org.platformlayer.auth.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class CheckServiceAccessRequest { + public CertificateChainInfo chain; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/CheckServiceAccessResponse.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/CheckServiceAccessResponse.java new file mode 100644 index 000000000..fd43c8594 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/CheckServiceAccessResponse.java @@ -0,0 +1,11 @@ +package org.platformlayer.auth.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class CheckServiceAccessResponse { + public String serviceAccount; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/PasswordCredentials.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/PasswordCredentials.java new file mode 100644 index 000000000..a401fd4e8 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/PasswordCredentials.java @@ -0,0 +1,10 @@ +package org.platformlayer.auth.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +@XmlAccessorType(XmlAccessType.FIELD) +public class PasswordCredentials { + public String username; + public String password; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/ProjectValidation.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/ProjectValidation.java new file mode 100644 index 000000000..4622ddf56 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/ProjectValidation.java @@ -0,0 +1,16 @@ +package org.platformlayer.auth.model; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +@XmlAccessorType(XmlAccessType.FIELD) +public class ProjectValidation { + public String id; + public String name; + + public byte[] secret; + + public List roles; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/RegistrationRequest.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/RegistrationRequest.java new file mode 100644 index 000000000..bd3463671 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/RegistrationRequest.java @@ -0,0 +1,12 @@ +package org.platformlayer.auth.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class RegistrationRequest { + public String username; + public String password; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/RegistrationResponse.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/RegistrationResponse.java new file mode 100644 index 000000000..c0fa32f94 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/RegistrationResponse.java @@ -0,0 +1,12 @@ +package org.platformlayer.auth.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class RegistrationResponse { + public Access access; + public String errorMessage; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/Role.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/Role.java new file mode 100644 index 000000000..291e3c71e --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/Role.java @@ -0,0 +1,10 @@ +package org.platformlayer.auth.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +@XmlAccessorType(XmlAccessType.FIELD) +public class Role { + public String name; + // public String description; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/RoleList.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/RoleList.java new file mode 100644 index 000000000..e0dbde815 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/RoleList.java @@ -0,0 +1,15 @@ +package org.platformlayer.auth.model; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "roles") +@XmlAccessorType(XmlAccessType.FIELD) +public class RoleList { + @XmlElement(name = "role") + public List roles; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/SignCertificateRequest.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/SignCertificateRequest.java new file mode 100644 index 000000000..9e9f284d7 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/SignCertificateRequest.java @@ -0,0 +1,13 @@ +package org.platformlayer.auth.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class SignCertificateRequest { + public String project; + public String csr; + public byte[] projectSecret; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/SignCertificateResponse.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/SignCertificateResponse.java new file mode 100644 index 000000000..2940b9844 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/SignCertificateResponse.java @@ -0,0 +1,14 @@ +package org.platformlayer.auth.model; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class SignCertificateResponse { + + public List certificates; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/Token.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/Token.java new file mode 100644 index 000000000..58bd53ab2 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/Token.java @@ -0,0 +1,12 @@ +package org.platformlayer.auth.model; + +import java.util.Date; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +@XmlAccessorType(XmlAccessType.FIELD) +public class Token { + public Date expires; + public String id; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/User.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/User.java new file mode 100644 index 000000000..5a007dac3 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/User.java @@ -0,0 +1,21 @@ +package org.platformlayer.auth.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "user") +@XmlAccessorType(XmlAccessType.FIELD) +public class User { + @XmlAttribute + public boolean enabled; + + @XmlAttribute + public String email; + + public String username; + + @XmlAttribute + public String id; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/UserValidation.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/UserValidation.java new file mode 100644 index 000000000..c5f03274f --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/UserValidation.java @@ -0,0 +1,12 @@ +package org.platformlayer.auth.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +@XmlAccessorType(XmlAccessType.FIELD) +public class UserValidation { + public String id; + public String name; + + // public byte[] secret; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/ValidateAccess.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/ValidateAccess.java new file mode 100644 index 000000000..a4bc31f6a --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/ValidateAccess.java @@ -0,0 +1,15 @@ +package org.platformlayer.auth.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class ValidateAccess { + public Token token; + + public UserValidation user; + + public ProjectValidation project; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/ValidateTokenResponse.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/ValidateTokenResponse.java new file mode 100644 index 000000000..a85fae124 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/ValidateTokenResponse.java @@ -0,0 +1,11 @@ +package org.platformlayer.auth.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class ValidateTokenResponse { + public ValidateAccess access; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/model/package-info.java b/auth/server-shared/src/main/java/org/platformlayer/auth/model/package-info.java new file mode 100644 index 000000000..7d3654a1e --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/model/package-info.java @@ -0,0 +1,3 @@ +@javax.xml.bind.annotation.XmlSchema(namespace = "http://platformlayer.org/auth/v1.0", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) +package org.platformlayer.auth.model; + diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/resources/Mapping.java b/auth/server-shared/src/main/java/org/platformlayer/auth/resources/Mapping.java new file mode 100644 index 000000000..4f35968b7 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/resources/Mapping.java @@ -0,0 +1,61 @@ +package org.platformlayer.auth.resources; + +import java.util.List; + +import org.platformlayer.auth.ProjectEntity; +import org.platformlayer.auth.UserEntity; +import org.platformlayer.auth.model.ProjectValidation; +import org.platformlayer.auth.model.Role; +import org.platformlayer.auth.model.User; +import org.platformlayer.auth.model.UserValidation; +import org.platformlayer.model.RoleId; + +import com.fathomdb.crypto.FathomdbCrypto; +import com.google.common.collect.Lists; + +public class Mapping { + + // public static RoleList mapToRoles(List roles) { + // RoleList roleList = new RoleList(); + // roleList.roles = roles; + // return roleList; + // } + + public static List mapToRoles(List roles) { + List roleList = Lists.newArrayList(); + for (RoleId role : roles) { + Role xmlRole = new Role(); + xmlRole.name = role.getKey(); + roleList.add(xmlRole); + } + return roleList; + } + + public static User mapToUser(UserEntity userInfo) { + User user = new User(); + user.enabled = true; + user.id = "" + userInfo.id; + user.username = userInfo.key; + user.email = userInfo.key; + return user; + } + + public static UserValidation mapToUserValidation(UserEntity userInfo) { + UserValidation user = new UserValidation(); + user.id = "" + userInfo.id; + user.name = userInfo.key; + // user.secret = AesUtils.serialize(userInfo.getUserSecret()); + return user; + } + + public static ProjectValidation mapToProject(ProjectEntity entity) { + ProjectValidation mapped = new ProjectValidation(); + mapped.id = "" + entity.id; + mapped.name = entity.name; + if (!entity.isLocked()) { + mapped.secret = FathomdbCrypto.serialize(entity.getProjectSecret()); + } + return mapped; + } + +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/resources/PlatformlayerAuthResourceBase.java b/auth/server-shared/src/main/java/org/platformlayer/auth/resources/PlatformlayerAuthResourceBase.java new file mode 100644 index 000000000..4d5589222 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/resources/PlatformlayerAuthResourceBase.java @@ -0,0 +1,64 @@ +package org.platformlayer.auth.resources; + +import java.security.cert.X509Certificate; +import java.util.List; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; + +import org.platformlayer.auth.keystone.KeystoneUserAuthenticator; +import org.platformlayer.auth.services.RegistrationService; +import org.platformlayer.web.HttpUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fathomdb.TimeSpan; + +public class PlatformlayerAuthResourceBase { + private static final Logger log = LoggerFactory.getLogger(PlatformlayerAuthResourceBase.class); + + protected static final String AUTH_HEADER = "X-Auth-Token"; + + public static final String JSONP = "application/javascript"; + public static final String APPLICATION_JSON = javax.ws.rs.core.MediaType.APPLICATION_JSON; + public static final String APPLICATION_XML = javax.ws.rs.core.MediaType.APPLICATION_XML; + + // @Inject + // protected AuthenticationFacade authentication; + + @Context + HttpHeaders httpHeaders; + + @Context + protected HttpServletRequest httpRequest; + + @Inject + protected KeystoneUserAuthenticator userAuthenticator; + + @Inject + protected RegistrationService registrationService; + + protected void throw404NotFound() { + throw new WebApplicationException(404); + } + + protected void throwUnauthorized() { + throw new WebApplicationException(401); + } + + protected void throwInternalError() { + throw new WebApplicationException(500); + } + + protected boolean isNullOrEmpty(List list) { + return (list == null) || (list.isEmpty()); + } + + protected X509Certificate[] getCertificateChain() { + return HttpUtils.getCertificateChain(httpRequest); + } + +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/server/GuiceAuthenticationConfig.java b/auth/server-shared/src/main/java/org/platformlayer/auth/server/GuiceAuthenticationConfig.java new file mode 100644 index 000000000..94312ec8a --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/server/GuiceAuthenticationConfig.java @@ -0,0 +1,25 @@ +package org.platformlayer.auth.server; + +import org.platformlayer.auth.services.CacheSystem; +import org.platformlayer.auth.services.TokenService; +import org.platformlayer.auth.services.crypto.SharedSecretTokenService; +import org.platformlayer.auth.services.memory.SimpleCacheSystem; +import org.platformlayer.crypto.EncryptionStoreProvider; + +import com.fathomdb.crypto.EncryptionStore; +import com.google.inject.AbstractModule; + +public class GuiceAuthenticationConfig extends AbstractModule { + + @Override + protected void configure() { + bind(EncryptionStore.class).toProvider(EncryptionStoreProvider.class); + + bind(TokenService.class).toProvider(SharedSecretTokenService.Provider.class).asEagerSingleton(); + + int cacheSize = 1000; + CacheSystem simpleCacheSystem = new SimpleCacheSystem(cacheSize); + bind(CacheSystem.class).toInstance(simpleCacheSystem); + } + +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/services/AsyncExecutor.java b/auth/server-shared/src/main/java/org/platformlayer/auth/services/AsyncExecutor.java new file mode 100644 index 000000000..3bff26493 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/services/AsyncExecutor.java @@ -0,0 +1,28 @@ +package org.platformlayer.auth.services; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import javax.inject.Singleton; + +import com.fathomdb.TimeSpan; + +@Singleton +public class AsyncExecutor { + final ExecutorService executors = Executors.newCachedThreadPool(); + final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2); + + public void schedule(TimeSpan delay, final Runnable runnable) { + scheduler.schedule(new Runnable() { + + @Override + public void run() { + executors.submit(runnable); + } + + }, delay.getTotalMilliseconds(), TimeUnit.MILLISECONDS); + } + +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/services/CacheSystem.java b/auth/server-shared/src/main/java/org/platformlayer/auth/services/CacheSystem.java new file mode 100644 index 000000000..a9616761a --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/services/CacheSystem.java @@ -0,0 +1,11 @@ +package org.platformlayer.auth.services; + +import java.io.Serializable; + +import com.fathomdb.TimeSpan; + +public interface CacheSystem { + T lookup(String key, Class clazz); + + void put(String key, TimeSpan validity, Serializable value); +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/services/LoginLimits.java b/auth/server-shared/src/main/java/org/platformlayer/auth/services/LoginLimits.java new file mode 100644 index 000000000..c8c2a7441 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/services/LoginLimits.java @@ -0,0 +1,75 @@ +package org.platformlayer.auth.services; + +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.http.HttpServletRequest; + +import com.fathomdb.TimeSpan; +import com.fathomdb.ratelimit.RateLimit; +import com.fathomdb.ratelimit.RateLimitSystem; + +@Singleton +public class LoginLimits { + final RateLimit[] FAILED_LOGINS_BY_USERNAME; + final RateLimit[] FAILED_LOGINS_BY_IP; + + @Inject + public LoginLimits(RateLimitSystem rateLimitSystem) { + FAILED_LOGINS_BY_USERNAME = new RateLimit[3]; + + FAILED_LOGINS_BY_USERNAME[0] = new RateLimit(rateLimitSystem, "loginfail/user/5m/", TimeSpan.FIVE_MINUTES, 10); + FAILED_LOGINS_BY_USERNAME[1] = new RateLimit(rateLimitSystem, "loginfail/user/1h/", TimeSpan.ONE_HOUR, 20); + FAILED_LOGINS_BY_USERNAME[2] = new RateLimit(rateLimitSystem, "loginfail/user/1d/", TimeSpan.ONE_DAY, 30); + + FAILED_LOGINS_BY_IP = new RateLimit[3]; + + FAILED_LOGINS_BY_IP[0] = new RateLimit(rateLimitSystem, "loginfail/ip/5m/", TimeSpan.FIVE_MINUTES, 10); + FAILED_LOGINS_BY_IP[1] = new RateLimit(rateLimitSystem, "loginfail/ip/1h/", TimeSpan.ONE_HOUR, 20); + FAILED_LOGINS_BY_IP[2] = new RateLimit(rateLimitSystem, "loginfail/ip/1d/", TimeSpan.ONE_DAY, 30); + } + + public boolean isOverLimit(HttpServletRequest httpRequest, String username) { + if (username != null) { + for (RateLimit rateLimit : FAILED_LOGINS_BY_USERNAME) { + if (rateLimit.isOverLimit(username)) { + return true; + } + } + } + + String ip = getIp(httpRequest); + if (ip != null) { + for (RateLimit rateLimit : FAILED_LOGINS_BY_IP) { + if (rateLimit.isOverLimit(ip)) { + return true; + } + } + } + + return false; + } + + private String getIp(HttpServletRequest httpRequest) { + if (httpRequest == null) { + return null; + } + + String ip = httpRequest.getRemoteAddr(); + return ip; + } + + public void recordFail(HttpServletRequest httpRequest, String username) { + if (username != null) { + for (RateLimit rateLimit : FAILED_LOGINS_BY_USERNAME) { + rateLimit.add(username, 1); + } + } + + String ip = getIp(httpRequest); + if (ip != null) { + for (RateLimit rateLimit : FAILED_LOGINS_BY_IP) { + rateLimit.add(ip, 1); + } + } + } +} \ No newline at end of file diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/services/LoginService.java b/auth/server-shared/src/main/java/org/platformlayer/auth/services/LoginService.java new file mode 100644 index 000000000..f02c84c4e --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/services/LoginService.java @@ -0,0 +1,106 @@ +package org.platformlayer.auth.services; + +import java.security.cert.X509Certificate; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; + +import org.platformlayer.auth.AuthenticatorException; +import org.platformlayer.auth.CertificateAuthenticationRequest; +import org.platformlayer.auth.CertificateAuthenticationResponse; +import org.platformlayer.auth.UserEntity; +import org.platformlayer.auth.keystone.KeystoneUserAuthenticator; +import org.platformlayer.auth.model.AuthenticateRequest; +import org.platformlayer.auth.model.AuthenticateResponse; +import org.platformlayer.web.HttpUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fathomdb.TimeSpan; + +public class LoginService { + private static final Logger log = LoggerFactory.getLogger(LoginService.class); + + @Inject + TokenHelpers tokenHelpers; + + @Inject + KeystoneUserAuthenticator userAuthenticator; + + public static final TimeSpan OVER_LIMIT_DELAY = TimeSpan.fromMilliseconds(2000); + + public AuthenticateResponse authenticate(HttpServletRequest httpRequest, AuthenticateRequest request) { + AuthenticateResponse response = new AuthenticateResponse(); + + String username = null; + + UserEntity user = null; + + if (request.auth.passwordCredentials != null) { + username = request.auth.passwordCredentials.username; + String password = request.auth.passwordCredentials.password; + + try { + user = userAuthenticator.authenticate(username, password); + } catch (AuthenticatorException e) { + // An exception indicates something went wrong (i.e. not just + // bad credentials) + log.warn("Error while getting user info", e); + throw new IllegalStateException("Error while getting user info", e); + } + } else if (request.auth.certificateCredentials != null) { + username = request.auth.certificateCredentials.username; + + X509Certificate[] certificateChain = HttpUtils.getCertificateChain(httpRequest); + if (certificateChain == null) { + return null; + } + + byte[] challengeResponse = request.auth.certificateCredentials.challengeResponse; + + CertificateAuthenticationRequest details = new CertificateAuthenticationRequest(); + details.certificateChain = certificateChain; + details.username = username; + // details.projectKey = projectKey; + details.challengeResponse = challengeResponse; + + CertificateAuthenticationResponse result = null; + try { + result = userAuthenticator.authenticate(details); + } catch (AuthenticatorException e) { + log.warn("Error while authenticating by certificate", e); + throw new IllegalStateException("Error while authenticating by certificate", e); + } + + if (result == null) { + return null; + } + + if (challengeResponse != null) { + if (result.user == null) { + return null; + } + + user = (UserEntity) result.user; + } else { + log.debug("Returning authentication challenge for user: " + username); + + response.challenge = result.challenge; + return response; + } + } else { + return null; + } + + if (user == null) { + log.debug("Authentication request failed. Username=" + username); + return null; + } + + log.debug("Successful authentication for user: " + user.key); + + response.access = tokenHelpers.buildAccess(user); + + return response; + } +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/services/PkiService.java b/auth/server-shared/src/main/java/org/platformlayer/auth/services/PkiService.java new file mode 100644 index 000000000..b9f8787e1 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/services/PkiService.java @@ -0,0 +1,15 @@ +package org.platformlayer.auth.services; + +import java.security.cert.X509Certificate; +import java.util.List; + +import org.platformlayer.auth.ProjectEntity; +import org.platformlayer.auth.services.pki.PkiServiceImpl; +import org.platformlayer.ops.OpsException; + +import com.google.inject.ImplementedBy; + +@ImplementedBy(PkiServiceImpl.class) +public interface PkiService { + List signCsr(ProjectEntity project, String csr) throws OpsException; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/services/RegistrationService.java b/auth/server-shared/src/main/java/org/platformlayer/auth/services/RegistrationService.java new file mode 100644 index 000000000..88cf4c9a4 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/services/RegistrationService.java @@ -0,0 +1,12 @@ +package org.platformlayer.auth.services; + +import org.platformlayer.CustomerFacingException; +import org.platformlayer.auth.OpsUser; +import org.platformlayer.auth.services.registration.RegistrationServiceImpl; + +import com.google.inject.ImplementedBy; + +@ImplementedBy(RegistrationServiceImpl.class) +public interface RegistrationService { + public OpsUser registerUser(String username, String password) throws CustomerFacingException; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/services/SystemAuthenticator.java b/auth/server-shared/src/main/java/org/platformlayer/auth/services/SystemAuthenticator.java new file mode 100644 index 000000000..bfa16028a --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/services/SystemAuthenticator.java @@ -0,0 +1,9 @@ +package org.platformlayer.auth.services; + +import org.platformlayer.auth.AuthenticatorException; +import org.platformlayer.auth.ServiceAccountEntity; +import org.platformlayer.auth.model.CertificateChainInfo; + +public interface SystemAuthenticator { + ServiceAccountEntity authenticate(CertificateChainInfo certChain) throws AuthenticatorException; +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/services/TokenHelpers.java b/auth/server-shared/src/main/java/org/platformlayer/auth/services/TokenHelpers.java new file mode 100644 index 000000000..5863a7ae0 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/services/TokenHelpers.java @@ -0,0 +1,70 @@ +package org.platformlayer.auth.services; + +import java.util.Date; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.platformlayer.RepositoryException; +import org.platformlayer.auth.ProjectEntity; +import org.platformlayer.auth.UserEntity; +import org.platformlayer.auth.keystone.AuthenticationSecrets; +import org.platformlayer.auth.keystone.KeystoneUserAuthenticator; +import org.platformlayer.auth.model.Access; +import org.platformlayer.auth.model.Token; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fathomdb.TimeSpan; +import com.google.common.collect.Lists; + +@Singleton +public class TokenHelpers { + private static final Logger log = LoggerFactory.getLogger(TokenHelpers.class); + + protected static final TimeSpan TOKEN_VALIDITY = new TimeSpan("1h"); + + @Inject + TokenService tokenService; + + @Inject + AuthenticationSecrets authSecrets; + + @Inject + KeystoneUserAuthenticator userAuthenticator; + + public Access buildAccess(UserEntity user) { + byte[] tokenSecret = authSecrets.buildToken(user.getUserSecret()); + + TokenInfo token = buildToken("" + user.getId(), tokenSecret); + + Access access = new Access(); + // response.access.serviceCatalog = serviceMapper.getServices(userInfo, + // project); + access.token = new Token(); + access.token.expires = token.expiration; + access.token.id = tokenService.encodeToken(token); + + access.projects = Lists.newArrayList(); + try { + for (ProjectEntity project : userAuthenticator.listProjects(user)) { + access.projects.add(project.getName()); + } + } catch (RepositoryException e) { + log.warn("Error while listing projects for user: " + user.key, e); + throw new IllegalStateException("Error listing projects for user", e); + } + + return access; + } + + private TokenInfo buildToken(String userId, byte[] tokenSecret) { + Date now = new Date(); + Date expiration = TOKEN_VALIDITY.addTo(now); + + byte flags = 0; + TokenInfo tokenInfo = new TokenInfo(flags, userId, expiration, tokenSecret); + + return tokenInfo; + } +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/services/TokenInfo.java b/auth/server-shared/src/main/java/org/platformlayer/auth/services/TokenInfo.java new file mode 100644 index 000000000..f81602b66 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/services/TokenInfo.java @@ -0,0 +1,22 @@ +package org.platformlayer.auth.services; + +import java.util.Date; + +public class TokenInfo { + public final byte flags; + public final String userId; + public final Date expiration; + public final byte[] tokenSecret; + + public TokenInfo(byte flags, String userId, Date expiration, byte[] tokenSecret) { + this.flags = flags; + this.userId = userId; + this.expiration = expiration; + this.tokenSecret = tokenSecret; + } + + public boolean hasExpired() { + return expiration.getTime() < System.currentTimeMillis(); + } + +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/services/TokenService.java b/auth/server-shared/src/main/java/org/platformlayer/auth/services/TokenService.java new file mode 100644 index 000000000..43989399f --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/services/TokenService.java @@ -0,0 +1,7 @@ +package org.platformlayer.auth.services; + +public interface TokenService { + TokenInfo decodeToken(String token); + + String encodeToken(TokenInfo token); +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/services/crypto/SharedSecretTokenService.java b/auth/server-shared/src/main/java/org/platformlayer/auth/services/crypto/SharedSecretTokenService.java new file mode 100644 index 000000000..f72bf1248 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/services/crypto/SharedSecretTokenService.java @@ -0,0 +1,198 @@ +package org.platformlayer.auth.services.crypto; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Date; + +import javax.crypto.interfaces.PBEKey; +import javax.crypto.spec.SecretKeySpec; +import javax.inject.Inject; + +import org.platformlayer.auth.services.TokenInfo; +import org.platformlayer.auth.services.TokenService; +import org.platformlayer.crypto.CryptoUtils; +import org.platformlayer.crypto.SecureComparison; +import org.platformlayer.metrics.Instrumented; + +import com.fathomdb.Configuration; +import com.fathomdb.Utf8; +import com.fathomdb.crypto.KeyDerivationFunctions; +import com.fathomdb.utils.Base64; +import com.google.common.io.ByteStreams; + +@Instrumented +public class SharedSecretTokenService implements TokenService { + private final SecretKeySpec userSecretKeySpec; + + // To keep the numbers smaller; we quantize time and offset it + static final long TIME_GRANULARITY = 60000L; + static final long TIME_OFFSET = 1234567890; + + public static class Provider implements javax.inject.Provider { + + @Inject + Configuration configuration; + + @Override + public SharedSecretTokenService get() { + String secret = configuration.find("sharedsecret"); + if (secret == null) { + throw new IllegalStateException("sharedsecret is required"); + } + SharedSecretTokenService tokenService = new SharedSecretTokenService(secret); + return tokenService; + } + } + + static SecretKeySpec deriveHmacSha1Key(String keyData) { + // We want a consistent salt; it can't be empty + byte[] salt = Utf8.getBytes(keyData); + int keySize = 128; // ?? + int iterationCount = 1000; + PBEKey pbeKey = KeyDerivationFunctions.doPbkdf2(iterationCount, salt, keyData, keySize); + + return CryptoUtils.buildHmacSha1Key(pbeKey.getEncoded()); + } + + public SharedSecretTokenService(String secret) { + this.userSecretKeySpec = deriveHmacSha1Key(secret); + } + + @Override + public TokenInfo decodeToken(String token) { + if (token == null) { + return null; + } + + try { + String base64 = unescapeBase64(token); + byte[] buffer = Base64.decode(base64); + + ByteArrayInputStream bais = new ByteArrayInputStream(buffer); + byte flags = (byte) bais.read(); + if (flags == -1) { + return null; + } + + String expiration = readNullTerminatedString(bais); + String username = readNullTerminatedString(bais); + byte[] tokenSecret = readLengthPrefixByteArray(bais); + + byte[] signature = new byte[CryptoUtils.HMAC_SHA1_BYTES]; + if (bais.read(signature) != CryptoUtils.HMAC_SHA1_BYTES) { + return null; + } + + SecretKeySpec secretKeySpec = userSecretKeySpec; + byte[] actualSignature = CryptoUtils.hmacSha1(secretKeySpec, buffer, 0, buffer.length + - CryptoUtils.HMAC_SHA1_BYTES); + + if (!SecureComparison.equal(actualSignature, signature)) { + return null; + } + + long roundedTime = Long.parseLong(expiration, 16); + long time = (roundedTime * TIME_GRANULARITY) + TIME_OFFSET; + + return new TokenInfo(flags, username, new Date(time), tokenSecret); + } catch (Exception e) { + return null; + } + } + + private static String readNullTerminatedString(InputStream is) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + while (true) { + int nextByte = is.read(); + if (nextByte == -1) { + break; + } + if (nextByte == 0) { + break; + } + baos.write(nextByte); + } + + return Utf8.toString(baos); + } + + private static byte[] readLengthPrefixByteArray(InputStream is) throws IOException { + int length = is.read(); + if (length == -1) { + throw new EOFException(); + } + + if (length == 0) { + return null; + } + + length--; + + byte[] data = new byte[length]; + ByteStreams.readFully(is, data, 0, length); + return data; + } + + @Override + public String encodeToken(TokenInfo tokenInfo) { + long time = tokenInfo.expiration.getTime(); + + long roundedTime = ((time - TIME_OFFSET) + TIME_GRANULARITY - 1) / TIME_GRANULARITY; + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + baos.write(tokenInfo.flags); + baos.write(Utf8.getBytes(Long.toHexString(roundedTime))); + baos.write(0); + baos.write(Utf8.getBytes(tokenInfo.userId)); + baos.write(0); + if (tokenInfo.tokenSecret != null) { + if (tokenInfo.tokenSecret.length >= 100) { + // We might want to use a variable length integer encoding in future + throw new IllegalStateException(); + } + baos.write(tokenInfo.tokenSecret.length + 1); + baos.write(tokenInfo.tokenSecret); + } else { + baos.write(0); + } + } catch (IOException e) { + throw new IllegalStateException(); + } + + SecretKeySpec secretKeySpec = userSecretKeySpec; + byte[] signed = CryptoUtils.hmacSha1(secretKeySpec, baos.toByteArray()); + if (signed.length != CryptoUtils.HMAC_SHA1_BYTES) { + throw new IllegalStateException(); + } + + try { + baos.write(signed); + } catch (IOException e) { + throw new IllegalStateException(); + } + + String base64 = Base64.encode(baos.toByteArray()); + String encoded = escapeBase64(base64); + + return encoded; + } + + static String escapeBase64(String s) { + s = s.replace('+', '_'); + s = s.replace('/', '.'); + s = s.replace('=', '-'); + return s; + } + + static String unescapeBase64(String s) { + s = s.replace('_', '+'); + s = s.replace('.', '/'); + s = s.replace('-', '='); + return s; + } + +} diff --git a/auth/server-shared/src/main/java/org/openstack/keystone/services/memory/SimpleCacheSystem.java b/auth/server-shared/src/main/java/org/platformlayer/auth/services/memory/SimpleCacheSystem.java similarity index 87% rename from auth/server-shared/src/main/java/org/openstack/keystone/services/memory/SimpleCacheSystem.java rename to auth/server-shared/src/main/java/org/platformlayer/auth/services/memory/SimpleCacheSystem.java index 1c33c7337..32f30dc10 100644 --- a/auth/server-shared/src/main/java/org/openstack/keystone/services/memory/SimpleCacheSystem.java +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/services/memory/SimpleCacheSystem.java @@ -1,4 +1,4 @@ -package org.openstack.keystone.services.memory; +package org.platformlayer.auth.services.memory; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -9,14 +9,16 @@ import java.util.LinkedHashMap; import java.util.Map.Entry; -import org.apache.log4j.Logger; -import org.openstack.keystone.services.CacheSystem; -import org.platformlayer.CastUtils; -import org.platformlayer.IoUtils; -import org.platformlayer.TimeSpan; +import org.platformlayer.auth.services.CacheSystem; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fathomdb.Casts; +import com.fathomdb.TimeSpan; +import com.fathomdb.io.IoUtils; public class SimpleCacheSystem implements CacheSystem { - static final Logger log = Logger.getLogger(SimpleCacheSystem.class); + private static final Logger log = LoggerFactory.getLogger(SimpleCacheSystem.class); static class LruHashMap { final LinkedHashMap map; @@ -78,7 +80,7 @@ public T lookup(String key, Class clazz) { ObjectInputStream ois = null; try { ois = new ObjectInputStream(new ByteArrayInputStream(entry.value)); - T t = CastUtils.as(ois.readObject(), clazz); + T t = Casts.as(ois.readObject(), clazz); return t; } catch (IOException e) { log.warn("Ignoring error deserializing from cache", e); diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/services/pki/PkiServiceImpl.java b/auth/server-shared/src/main/java/org/platformlayer/auth/services/pki/PkiServiceImpl.java new file mode 100644 index 000000000..f80872f52 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/services/pki/PkiServiceImpl.java @@ -0,0 +1,46 @@ +package org.platformlayer.auth.services.pki; + +import java.security.cert.X509Certificate; +import java.util.List; + +import javax.inject.Inject; + +import org.platformlayer.RepositoryException; +import org.platformlayer.auth.ProjectEntity; +import org.platformlayer.auth.UserDatabase; +import org.platformlayer.auth.services.PkiService; +import org.platformlayer.crypto.SimpleCertificateAuthority; +import org.platformlayer.metrics.Instrumented; +import org.platformlayer.ops.OpsException; + +import com.fathomdb.crypto.CertificateAndKey; +import com.google.common.collect.Lists; + +@Instrumented +public class PkiServiceImpl implements PkiService { + @Inject + UserDatabase repository; + + @Override + public List signCsr(ProjectEntity project, String csr) throws OpsException { + CertificateAndKey projectPki; + try { + projectPki = repository.getProjectPki(project); + } catch (RepositoryException e) { + throw new OpsException("Error getting project PKI info", e); + } + + SimpleCertificateAuthority ca = new SimpleCertificateAuthority(); + ca.caCertificate = projectPki.getCertificateChain(); + ca.caPrivateKey = projectPki.getPrivateKey(); + + X509Certificate certificate = ca.signCsr(csr); + + List chain = Lists.newArrayList(); + chain.add(certificate); + for (X509Certificate cert : projectPki.getCertificateChain()) { + chain.add(cert); + } + return chain; + } +} diff --git a/auth/server-shared/src/main/java/org/platformlayer/auth/services/registration/RegistrationServiceImpl.java b/auth/server-shared/src/main/java/org/platformlayer/auth/services/registration/RegistrationServiceImpl.java new file mode 100644 index 000000000..05eebd179 --- /dev/null +++ b/auth/server-shared/src/main/java/org/platformlayer/auth/services/registration/RegistrationServiceImpl.java @@ -0,0 +1,81 @@ +package org.platformlayer.auth.services.registration; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.platformlayer.CustomerFacingException; +import org.platformlayer.RepositoryException; +import org.platformlayer.auth.OpsUser; +import org.platformlayer.auth.UserDatabase; +import org.platformlayer.auth.services.RegistrationService; +import org.platformlayer.metrics.Instrumented; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Strings; + +@Singleton +@Instrumented +public class RegistrationServiceImpl implements RegistrationService { + private static final Logger log = LoggerFactory.getLogger(RegistrationServiceImpl.class); + + private static final int MIN_PASSWORD_LENGTH = 6; + + @Inject + UserDatabase repository; + + @Override + public OpsUser registerUser(String username, String password) throws CustomerFacingException { + if (Strings.isNullOrEmpty(username)) { + throw CustomerFacingException.buildRequiredField("username"); + } + + if (Strings.isNullOrEmpty(password)) { + throw CustomerFacingException.buildRequiredField("password"); + } + + password = password.trim(); + username = username.trim(); + + checkPassword(password); + + checkUsername(username); + + OpsUser user; + try { + user = repository.findUser(username); + if (user != null) { + // TODO: Should we hide this fact? + throw CustomerFacingException + .buildFieldError("username", "duplicate", "Username is already registered"); + } + + user = repository.createUser(username, password, null); + + // TODO: We reserve @@, to prevent collisions + // TODO: Is this good enough? What if project already exists? + String projectKey = "user@@" + username.toLowerCase(); + repository.createProject(projectKey, user); + } catch (RepositoryException e) { + log.warn("Repository error creating user", e); + throw CustomerFacingException.wrap(e); + } + + return user; + } + + private void checkUsername(String email) throws CustomerFacingException { + if (!email.contains("@")) { + throw CustomerFacingException.buildFieldError("email", "invalid", "Email address is invalid"); + } + // TODO: More verification + } + + private void checkPassword(String password) throws CustomerFacingException { + if (password.length() < MIN_PASSWORD_LENGTH) { + throw CustomerFacingException.buildFieldError("password", "invalid", "Password must be at least " + + MIN_PASSWORD_LENGTH + " characters"); + } + // TODO: Minimum complexity? + } +} diff --git a/auth/server-shared/src/main/resources/log4j.properties b/auth/server-shared/src/main/resources/log4j.properties deleted file mode 100644 index 9e3571975..000000000 --- a/auth/server-shared/src/main/resources/log4j.properties +++ /dev/null @@ -1,8 +0,0 @@ -log4j.rootLogger=DEBUG, CONSOLE - -log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender -log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout -log4j.appender.CONSOLE.layout.ConversionPattern=%d [%t] %-5p %c - %m%n - -# Dial down logging on standard libraries -log4j.logger.org.eclipse.jetty=INFO diff --git a/auth/server-user/AuthUserServer.launch b/auth/server-user/AuthUserServer.launch deleted file mode 100644 index 57067c20b..000000000 --- a/auth/server-user/AuthUserServer.launch +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/auth/server-user/logback.xml b/auth/server-user/logback.xml new file mode 100644 index 000000000..c9dae7427 --- /dev/null +++ b/auth/server-user/logback.xml @@ -0,0 +1,20 @@ + + + + + + %d [%thread] %-5level %logger{35} - %msg %n + + + + + + + + + + + + + \ No newline at end of file diff --git a/auth/server-user/pom.xml b/auth/server-user/pom.xml index bf076e9da..b0d689364 100644 --- a/auth/server-user/pom.xml +++ b/auth/server-user/pom.xml @@ -1,22 +1,82 @@ - 4.0.0 - - - org.platformlayer - keystone-parent - 1.0-SNAPSHOT - - - keystone-webapp-user - Keystone :: Server :: User - - - - org.platformlayer - keystone-webapp-shared - ${version.project} - - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + 4.0.0 + + + org.platformlayer + keystone-parent + 1.0-SNAPSHOT + + + keystone-webapp-user + + + + postgresql + postgresql + + + + + org.apache.commons + commons-lang3 + 3.1 + + + + org.platformlayer + keystone-webapp-shared + ${version.project} + + + + ch.qos.logback + logback-classic + + + + org.platformlayer + metrics-client + + + + com.yammer.metrics + metrics-jetty + + + + org.apache.tomcat + tomcat-jdbc + + + + com.fathomdb + fathomdb-templates + ${project.version} + + + + + + + maven-assembly-plugin + 2.3 + + + src/main/assembly/tarfile.xml + + + + + make-assembly + package + + single + + + + + + diff --git a/auth/server-user/src/main/assembly/tarfile.xml b/auth/server-user/src/main/assembly/tarfile.xml new file mode 100644 index 000000000..d77102f55 --- /dev/null +++ b/auth/server-user/src/main/assembly/tarfile.xml @@ -0,0 +1,22 @@ + + bin + + tar.gz + + + + false + + + + + / + true + false + runtime + + + \ No newline at end of file diff --git a/auth/server-user/src/main/java/org/openstack/keystone/resources/user/Ec2TokensResource.java b/auth/server-user/src/main/java/org/openstack/keystone/resources/user/Ec2TokensResource.java deleted file mode 100644 index e875a9892..000000000 --- a/auth/server-user/src/main/java/org/openstack/keystone/resources/user/Ec2TokensResource.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.openstack.keystone.resources.user; - -import javax.ws.rs.Consumes; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.apache.log4j.Logger; -import org.openstack.keystone.model.Ec2ConvertTokenRequest; -import org.openstack.keystone.model.Ec2ConvertTokenResponse; -import org.openstack.keystone.resources.KeystoneResourceBase; - -@Path("/v2.0/ec2tokens") -public class Ec2TokensResource extends KeystoneResourceBase { - static final Logger log = Logger.getLogger(Ec2TokensResource.class); - - @POST - @Produces({ APPLICATION_JSON, APPLICATION_XML }) - @Consumes({ APPLICATION_JSON, APPLICATION_XML }) - public Ec2ConvertTokenResponse convertToken(Ec2ConvertTokenRequest request) { - throw new UnsupportedOperationException(); - - // - // boolean isSystem = false; - // TokenInfo tokenInfo = tryAuthenticate(isSystem, request.auth); - // - // if (tokenInfo == null) { - // throwUnauthorized(); - // } - // - // String scope = request.auth.tenantName; - // - // UserInfo userInfo = authentication.getUserInfo(isSystem, tokenInfo.userId); - // - // AuthenticateResponse response = new AuthenticateResponse(); - // response.access = new Access(); - // response.access.serviceCatalog = authentication.getServices(userInfo, scope); - // - // if (scope != null) { - // // If we are doing a scope auth, make sure we have access - // if (isNullOrEmpty(response.access.serviceCatalog)) { - // throwUnauthorized(); - // } - // } - // - // log.debug("Successful authentication for user: " + tokenInfo.userId); - // - // response.access.token = Mapping.mapToResponse(tokenInfo); - // response.access.token.id = authentication.signToken(tokenInfo); - // - // return response; - } -} diff --git a/auth/server-user/src/main/java/org/openstack/keystone/resources/user/Marshaller.java b/auth/server-user/src/main/java/org/openstack/keystone/resources/user/Marshaller.java new file mode 100644 index 000000000..af1776ec4 --- /dev/null +++ b/auth/server-user/src/main/java/org/openstack/keystone/resources/user/Marshaller.java @@ -0,0 +1,164 @@ +package org.openstack.keystone.resources.user; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import javax.inject.Singleton; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.platformlayer.xml.JaxbHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Splitter; + +@Singleton +public class Marshaller { + + private static final Logger log = LoggerFactory.getLogger(Marshaller.class); + + final ObjectMapper jsonMapper = buildJsonMapper(); + + private ObjectMapper buildJsonMapper() { + ObjectMapper mapper = new ObjectMapper(); + return mapper; + } + + public T read(HttpServletRequest httpRequest, Class clazz) { + InputStream is; + try { + is = httpRequest.getInputStream(); + } catch (IOException e) { + log.info("Error deserializing value", e); + return null; + } + + // // We do gzip compression directly (for now) + // String ce = httpRequest.getHeader("content-encoding"); + // if (ce != null) { + // if (ce.equalsIgnoreCase("gzip")) { + // is = new GZIPInputStream(is); + // } else { + // httpRequest.sendError(415); + // return; + // } + // } + + String contentType = httpRequest.getHeader("content-type"); + if (contentType == null) { + contentType = ""; + } else { + contentType = contentType.toLowerCase().trim(); + } + boolean json = true; + + if (contentType.equals("application/xml")) { + json = false; + } + + if (json) { + try { + T t = jsonMapper.readValue(is, clazz); + return t; + } catch (Exception e) { + log.info("Error deserializing value", e); + return null; + } + } else { + try { + T t = (T) JaxbHelper.deserializeXmlObject(is, clazz, false); + return t; + } catch (Exception e) { + log.info("Error deserializing value", e); + return null; + } + } + + } + + public void write(HttpServletRequest httpRequest, HttpServletResponse httpResponse, T response) { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + // // We do gzip compression directly (for now) + // String ce = httpRequest.getHeader("content-encoding"); + // if (ce != null) { + // if (ce.equalsIgnoreCase("gzip")) { + // is = new GZIPInputStream(is); + // } else { + // httpRequest.sendError(415); + // return; + // } + // } + + String accept = httpRequest.getHeader("accept"); + if (accept == null) { + accept = ""; + } + boolean json = true; + + for (String acceptType : Splitter.on(',').split(accept)) { + int semiIndex = acceptType.indexOf(';'); + if (semiIndex != -1) { + acceptType = acceptType.substring(0, semiIndex); + } + acceptType = acceptType.trim().toLowerCase(); + if (accept.equals("application/xml")) { + json = false; + break; + } else if (accept.equals("application/json")) { + json = true; + break; + } + } + + if (json) { + try { + jsonMapper.writeValue(baos, response); + } catch (Exception e) { + log.error("Error serializing value", e); + httpResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + return; + } + } else { + try { + JaxbHelper jaxb = JaxbHelper.get(response.getClass()); + boolean formatted = false; + jaxb.marshal(response, formatted, baos); + } catch (Exception e) { + log.error("Error serializing value", e); + httpResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + return; + } + } + + byte[] data = baos.toByteArray(); + if (json) { + httpResponse.setContentType("application/json"); + } else { + httpResponse.setContentType("application/xml"); + } + httpResponse.setContentLength(data.length); + + try { + ServletOutputStream os = httpResponse.getOutputStream(); + os.write(data); + os.flush(); + } catch (IOException e) { + // Not a lot we can do here ... we've already started sending data + log.error("Error flushing data", e); + // Try setting an error response + try { + httpResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } catch (Exception e2) { + log.warn("Unable to set error status", e2); + } + return; + } + } + +} diff --git a/auth/server-user/src/main/java/org/openstack/keystone/resources/user/PingResource.java b/auth/server-user/src/main/java/org/openstack/keystone/resources/user/PingResource.java new file mode 100644 index 000000000..e27fc5ef8 --- /dev/null +++ b/auth/server-user/src/main/java/org/openstack/keystone/resources/user/PingResource.java @@ -0,0 +1,16 @@ +package org.openstack.keystone.resources.user; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +@Path("/api/ping") +public class PingResource { + @GET + @Produces({ MediaType.APPLICATION_JSON }) + public String ping() { + return "{ 'message': 'pong' }"; + } + +} diff --git a/auth/server-user/src/main/java/org/openstack/keystone/resources/user/RegisterResource.java b/auth/server-user/src/main/java/org/openstack/keystone/resources/user/RegisterResource.java new file mode 100644 index 000000000..3a5af8e99 --- /dev/null +++ b/auth/server-user/src/main/java/org/openstack/keystone/resources/user/RegisterResource.java @@ -0,0 +1,62 @@ +package org.openstack.keystone.resources.user; + +import javax.inject.Inject; +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +import org.platformlayer.CustomerFacingException; +import org.platformlayer.auth.OpsUser; +import org.platformlayer.auth.UserEntity; +import org.platformlayer.auth.model.RegistrationRequest; +import org.platformlayer.auth.model.RegistrationResponse; +import org.platformlayer.auth.services.RegistrationService; +import org.platformlayer.auth.services.TokenHelpers; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Path("/api/register") +public class RegisterResource extends UserResourceBase { + private static final Logger log = LoggerFactory.getLogger(RegisterResource.class); + + @Inject + RegistrationService registrationService; + + @Inject + TokenHelpers tokenHelpers; + + @POST + @Produces({ APPLICATION_JSON, APPLICATION_XML }) + @Consumes({ APPLICATION_JSON, APPLICATION_XML }) + public RegistrationResponse doRegister(RegistrationRequest request) { + RegistrationResponse response = register(request); + + return response; + } + + private RegistrationResponse register(RegistrationRequest request) { + RegistrationResponse response = new RegistrationResponse(); + + String username = request.username; + String password = request.password; + + UserEntity userEntity; + try { + OpsUser user = registrationService.registerUser(username, password); + userEntity = (UserEntity) user; + } catch (CustomerFacingException e) { + response.errorMessage = e.getMessage(); + return response; + } + + if (userEntity == null) { + log.warn("Authentication request failed immediately after registration. Username=" + username); + throw new IllegalStateException(); + } + + response.access = tokenHelpers.buildAccess(userEntity); + return response; + } + +} diff --git a/auth/server-user/src/main/java/org/openstack/keystone/resources/user/RestLoginServlet.java b/auth/server-user/src/main/java/org/openstack/keystone/resources/user/RestLoginServlet.java new file mode 100644 index 000000000..ec6ed7b21 --- /dev/null +++ b/auth/server-user/src/main/java/org/openstack/keystone/resources/user/RestLoginServlet.java @@ -0,0 +1,125 @@ +package org.openstack.keystone.resources.user; + +import java.io.IOException; + +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.AsyncContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.WebApplicationException; + +import org.platformlayer.auth.model.AuthenticateRequest; +import org.platformlayer.auth.model.AuthenticateResponse; +import org.platformlayer.auth.services.AsyncExecutor; +import org.platformlayer.auth.services.LoginLimits; +import org.platformlayer.auth.services.LoginService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Strings; + +/** + * This is a servlet, so it can be async + * + */ +// @Path("/v2.0/tokens") +@Singleton +public class RestLoginServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + private static final Logger log = LoggerFactory.getLogger(RestLoginServlet.class); + + @Inject + LoginLimits limits; + + @Inject + Marshaller marshaller; + + @Inject + LoginService loginService; + + @Inject + AsyncExecutor asyncExecutor; + + @Override + protected void doPost(final HttpServletRequest httpRequest, final HttpServletResponse httpResponse) + throws ServletException, IOException { + + AuthenticateRequest request = marshaller.read(httpRequest, AuthenticateRequest.class); + + if (request == null) { + httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST); + return; + } + + processRequest(httpRequest, httpResponse, request, true); + } + + protected void processRequest(final HttpServletRequest httpRequest, final HttpServletResponse httpResponse, + final AuthenticateRequest request, boolean checkLimit) throws IOException { + try { + if (request.auth == null) { + httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); + return; + } + + String username = getUsername(request); + + if (Strings.isNullOrEmpty(username)) { + httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); + return; + } + + if (checkLimit && limits.isOverLimit(httpRequest, username)) { + final AsyncContext asyncContext = httpRequest.startAsync(httpRequest, httpResponse); + + asyncExecutor.schedule(LoginService.OVER_LIMIT_DELAY, new Runnable() { + @Override + public void run() { + try { + processRequest(httpRequest, httpResponse, request, false); + asyncContext.complete(); + } catch (Exception e) { + log.error("Unexpected error caught in async task", e); + } + } + }); + return; + } + + AuthenticateResponse authenticateResponse = loginService.authenticate(httpRequest, request); + if (authenticateResponse == null) { + limits.recordFail(httpRequest, username); + + httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); + return; + } + + marshaller.write(httpRequest, httpResponse, authenticateResponse); + } catch (WebApplicationException e) { + log.info("Returning exception from servlet", e); + httpResponse.sendError(e.getResponse().getStatus()); + } catch (Exception e) { + log.warn("Unexpected error in servlet", e); + httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } + + private String getUsername(AuthenticateRequest request) { + String username = null; + + if (request.auth.passwordCredentials != null) { + username = request.auth.passwordCredentials.username; + } else if (request.auth.certificateCredentials != null) { + username = request.auth.certificateCredentials.username; + } else { + username = null; + } + + return username; + } + +} diff --git a/auth/server-user/src/main/java/org/openstack/keystone/resources/user/TokensResource.java b/auth/server-user/src/main/java/org/openstack/keystone/resources/user/TokensResource.java deleted file mode 100644 index c7bee47da..000000000 --- a/auth/server-user/src/main/java/org/openstack/keystone/resources/user/TokensResource.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.openstack.keystone.resources.user; - -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -import org.apache.log4j.Logger; -import org.openstack.keystone.model.Access; -import org.openstack.keystone.model.AuthenticateRequest; -import org.openstack.keystone.model.AuthenticateResponse; -import org.openstack.keystone.resources.KeystoneResourceBase; -import org.openstack.keystone.resources.Mapping; -import org.openstack.keystone.server.ServiceMapper; -import org.openstack.keystone.services.AuthenticatorException; -import org.openstack.keystone.services.TokenInfo; -import org.openstack.keystone.services.UserInfo; - -@Path("/v2.0/tokens") -public class TokensResource extends KeystoneResourceBase { - static final Logger log = Logger.getLogger(TokensResource.class); - - @Inject - ServiceMapper serviceMapper; - - @POST - @Produces({ APPLICATION_JSON, APPLICATION_XML }) - @Consumes({ APPLICATION_JSON, APPLICATION_XML }) - public AuthenticateResponse authenticate(AuthenticateRequest request) { - boolean isSystem = false; - TokenInfo tokenInfo = null; - try { - tokenInfo = tryAuthenticate(isSystem, request.auth); - } catch (Exception e) { - // An exception indicates something went wrong (i.e. not just bad credentials) - log.warn("Error while authenticating", e); - throwInternalError(); - } - - if (tokenInfo == null) { - throwUnauthorized(); - } - - String scope = request.auth.tenantName; - - UserInfo userInfo = null; - try { - userInfo = authentication.getUserInfo(isSystem, tokenInfo.userId, tokenInfo.tokenSecret); - } catch (AuthenticatorException e) { - // An exception indicates something went wrong (i.e. not just bad credentials) - log.warn("Error while getting user info", e); - throwInternalError(); - } - - AuthenticateResponse response = new AuthenticateResponse(); - response.access = new Access(); - response.access.serviceCatalog = serviceMapper.getServices(userInfo, scope); - - if (scope != null) { - // If we are doing a scope auth, make sure we have access - if (isNullOrEmpty(response.access.serviceCatalog)) { - throwUnauthorized(); - } - } - - log.debug("Successful authentication for user: " + tokenInfo.userId); - - response.access.token = Mapping.mapToResponse(tokenInfo); - response.access.token.id = authentication.signToken(tokenInfo); - - return response; - } - - // @GET - // @Produces({ APPLICATION_JSON, APPLICATION_XML }) - // public TenantsList listTenants(@HeaderParam(AUTH_HEADER) String token) { - // // TODO: What is this call for? - // - // TokenInfo tokenInfo = authentication.validateToken(token); - // if (tokenInfo == null) { - // throwUnauthorized(); - // } - // - // TenantsList response = new TenantsList(); - // response.tenant = Lists.newArrayList(); - // - // String scope = tokenInfo.scope; - // if (scope == null) { - // // Unscoped token; no tenant access - // } else { - // Tenant tenant = new Tenant(); - // tenant.id = scope; - // tenant.enabled = true; - // tenant.name = scope; - // response.tenant.add(tenant); - // } - // - // return response; - // } - -} diff --git a/auth/server-user/src/main/java/org/openstack/keystone/resources/user/UserAuthServletModule.java b/auth/server-user/src/main/java/org/openstack/keystone/resources/user/UserAuthServletModule.java new file mode 100644 index 000000000..40c551447 --- /dev/null +++ b/auth/server-user/src/main/java/org/openstack/keystone/resources/user/UserAuthServletModule.java @@ -0,0 +1,55 @@ +package org.openstack.keystone.resources.user; + +import java.util.Map; + +import org.platformlayer.extensions.Extensions; +import org.platformlayer.extensions.HttpConfiguration; +import org.platformlayer.web.CORSFilter; + +import com.google.common.collect.Maps; +import com.google.inject.binder.AnnotatedBindingBuilder; +import com.sun.jersey.api.core.PackagesResourceConfig; +import com.sun.jersey.guice.JerseyServletModule; +import com.sun.jersey.guice.spi.container.servlet.GuiceContainer; + +public class UserAuthServletModule extends JerseyServletModule { + private final Extensions extensions; + + public UserAuthServletModule(Extensions extensions) { + super(); + this.extensions = extensions; + } + + @Override + protected void configureServlets() { + extensions.addHttpExtensions(new HttpConfiguration() { + @Override + public FilterKeyBindingBuilder filter(String urlPattern) { + return UserAuthServletModule.this.filter(urlPattern); + } + + @Override + public ServletKeyBindingBuilder serve(String urlPattern) { + return UserAuthServletModule.this.serve(urlPattern); + } + + @Override + public AnnotatedBindingBuilder bind(Class clazz) { + return UserAuthServletModule.this.bind(clazz); + } + }); + + bind(CORSFilter.class).asEagerSingleton(); + filter("/api/*").through(CORSFilter.class); + + bind(RegisterResource.class); + bind(PingResource.class); + + serve("/api/tokens").with(RestLoginServlet.class); + + Map params = Maps.newHashMap(); + params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "org.codehaus.jackson.jaxrs;com.fathomdb.jersey"); + serve("/*").with(GuiceContainer.class, params); + } + +} diff --git a/auth/server-user/src/main/java/org/openstack/keystone/resources/user/UserResourceBase.java b/auth/server-user/src/main/java/org/openstack/keystone/resources/user/UserResourceBase.java new file mode 100644 index 000000000..7199de72d --- /dev/null +++ b/auth/server-user/src/main/java/org/openstack/keystone/resources/user/UserResourceBase.java @@ -0,0 +1,8 @@ +package org.openstack.keystone.resources.user; + +import org.platformlayer.auth.resources.PlatformlayerAuthResourceBase; + +public class UserResourceBase extends PlatformlayerAuthResourceBase { + // private static final Logger log = LoggerFactory.getLogger(UserResourceBase.class); + +} diff --git a/auth/server-user/src/main/java/org/openstack/keystone/server/KeystoneUserServer.java b/auth/server-user/src/main/java/org/openstack/keystone/server/KeystoneUserServer.java index 8b22d167b..86f8d6342 100644 --- a/auth/server-user/src/main/java/org/openstack/keystone/server/KeystoneUserServer.java +++ b/auth/server-user/src/main/java/org/openstack/keystone/server/KeystoneUserServer.java @@ -2,50 +2,99 @@ import java.io.File; import java.util.EnumSet; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; -import org.eclipse.jetty.server.DispatcherType; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.servlet.DefaultServlet; -import org.eclipse.jetty.servlet.FilterHolder; -import org.eclipse.jetty.servlet.ServletContextHandler; +import org.openstack.keystone.resources.user.UserAuthServletModule; import org.platformlayer.WellKnownPorts; +import org.platformlayer.auth.KeystoneJdbcModule; +import org.platformlayer.auth.keystone.KeystoneOpsUserModule; +import org.platformlayer.auth.server.GuiceAuthenticationConfig; +import org.platformlayer.auth.services.LoginLimits; +import org.platformlayer.auth.services.LoginService; +import org.platformlayer.cache.CacheModule; +import org.platformlayer.config.ConfigurationModule; +import org.platformlayer.extensions.Extensions; +import org.platformlayer.metrics.MetricReporter; +import org.platformlayer.metrics.client.codahale.CodahaleMetricsModule; -import com.google.inject.servlet.GuiceFilter; +import com.fathomdb.Configuration; +import com.fathomdb.config.ConfigurationImpl; +import com.fathomdb.discovery.Discovery; +import com.fathomdb.server.http.SslOption; +import com.fathomdb.server.http.WebServerBuilder; +import com.google.common.collect.Lists; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Module; public class KeystoneUserServer { - private Server server; + private Server jettyServer; + + @Inject + MetricReporter metricReporter; + + @Inject + WebServerBuilder serverBuilder; + + @Inject + Injector injector; + + @Inject + Configuration configuration; + + @Inject + LoginService loginService; + + @Inject + LoginLimits loginLimits; public static void main(String[] args) throws Exception { - File base = new File(".").getCanonicalFile(); + List modules = Lists.newArrayList(); - KeystoneUserServer server = new KeystoneUserServer(); - server.start(base, WellKnownPorts.PORT_PLATFORMLAYER_AUTH_USER); - } + ConfigurationModule configurationModule = new ConfigurationModule(); + modules.add(configurationModule); + + Discovery discovery = Discovery.build(); + + ConfigurationImpl configuration = configurationModule.getConfiguration(); + Extensions extensions = new Extensions(configuration, discovery); - public void start(File base, int port) throws Exception { - this.server = new Server(port); + modules.add(new CacheModule()); + modules.add(new GuiceAuthenticationConfig()); + modules.add(new KeystoneJdbcModule()); + modules.add(new KeystoneOpsUserModule()); + modules.add(new CodahaleMetricsModule()); + modules.add(new UserAuthServletModule(extensions)); - ServletContextHandler context = new ServletContextHandler(); - context.setContextPath("/"); - server.setHandler(context); + Injector injector = Guice.createInjector(modules); - context.addEventListener(new UserServerConfig()); + KeystoneUserServer server = injector.getInstance(KeystoneUserServer.class); + server.start(WellKnownPorts.PORT_PLATFORMLAYER_AUTH_USER); + } + + public void start(int port) throws Exception { + EnumSet options = EnumSet.of(SslOption.AllowAnyClientCertificate, SslOption.WantClientCertificate); - // Must add DefaultServlet for embedded Jetty - // Failing to do this will cause 404 errors. - context.addServlet(DefaultServlet.class, "/"); + serverBuilder.addHttpsConnector(port, options); + serverBuilder.addGuiceContext("/", injector); - FilterHolder filterHolder = new FilterHolder(GuiceFilter.class); - context.addFilter(filterHolder, "*", EnumSet.of(DispatcherType.REQUEST)); + Map wars = configuration.getChildProperties("war."); + for (Map.Entry war : wars.entrySet()) { + serverBuilder.addWar(war.getKey(), new File(war.getValue())); + } - context.setClassLoader(Thread.currentThread().getContextClassLoader()); + this.jettyServer = serverBuilder.start(); - server.start(); + metricReporter.start(); } public void stop() throws Exception { - if (server != null) { - server.stop(); + if (jettyServer != null) { + jettyServer.stop(); } } } diff --git a/auth/server-user/src/main/java/org/openstack/keystone/server/ServiceMapper.java b/auth/server-user/src/main/java/org/openstack/keystone/server/ServiceMapper.java deleted file mode 100644 index 0f4f2df1d..000000000 --- a/auth/server-user/src/main/java/org/openstack/keystone/server/ServiceMapper.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.openstack.keystone.server; - -import java.util.Collection; -import java.util.List; - -import javax.inject.Inject; - -import org.apache.log4j.Logger; -import org.openstack.keystone.model.Service; -import org.openstack.keystone.services.GroupToTenantMapper; -import org.openstack.keystone.services.ServiceDictionary; -import org.openstack.keystone.services.TenantInfo; -import org.openstack.keystone.services.UserInfo; - -import com.google.common.base.Objects; -import com.google.common.collect.Lists; - -public class ServiceMapper { - static final Logger log = Logger.getLogger(ServiceMapper.class); - - @Inject - ServiceDictionary serviceDictionary; - - @Inject - GroupToTenantMapper groupToTenantMapper; - - public List getServices(UserInfo userInfo, String filterTenantId) { - Collection groups = userInfo.groups; - List services = Lists.newArrayList(); - for (String group : groups) { - TenantInfo tenantInfo = groupToTenantMapper.mapGroupToTenant(group); - if (tenantInfo != null) { - if (filterTenantId != null && !Objects.equal(filterTenantId, tenantInfo.tenantId)) { - continue; - } - - Service service = serviceDictionary.getServiceInfo(tenantInfo.serviceKey, tenantInfo.tenantId); - if (service == null) { - log.warn("Could not resolve service: " + tenantInfo.serviceKey); - } else { - services.add(service); - } - } - } - - return services; - } -} diff --git a/auth/server-user/src/main/java/org/openstack/keystone/server/UserServerConfig.java b/auth/server-user/src/main/java/org/openstack/keystone/server/UserServerConfig.java deleted file mode 100644 index 7a3738ba5..000000000 --- a/auth/server-user/src/main/java/org/openstack/keystone/server/UserServerConfig.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.openstack.keystone.server; - -import java.util.Map; - -import org.openstack.keystone.resources.user.TokensResource; - -import com.google.common.collect.Maps; -import com.google.inject.Guice; -import com.google.inject.Injector; -import com.google.inject.servlet.GuiceServletContextListener; -import com.sun.jersey.api.core.PackagesResourceConfig; -import com.sun.jersey.guice.JerseyServletModule; -import com.sun.jersey.guice.spi.container.servlet.GuiceContainer; - -public class UserServerConfig extends GuiceServletContextListener { - - @Override - protected Injector getInjector() { - return Guice.createInjector(new GuiceAuthenticationConfig(), new JerseyServletModule() { - @Override - protected void configureServlets() { - bind(TokensResource.class); - - Map params = Maps.newHashMap(); - params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "org.codehaus.jackson.jaxrs"); - serve("/*").with(GuiceContainer.class, params); - } - }); - } -} diff --git a/auth/updateschemas.sh b/auth/updateschemas.sh index fb92e8399..7f0a372a3 100755 --- a/auth/updateschemas.sh +++ b/auth/updateschemas.sh @@ -1,11 +1,17 @@ #!/bin/bash +set -e + # Generate the schema files -mvn generate-resources +pushd client +mvn jaxb2:schemagen +popd # Copy the generated schema(s) -cp server-shared/target/schemas/schema1.xsd client/src/main/schemas/keystone.xsd +cp server-shared/target/generated-resources/schemagen/schema1.xsd client/src/main/schemas/keystone.xsd # Update the bindings to the schema files -mvn generate-resources +pushd client +mvn jaxb2:xjc +popd diff --git a/bin/pl b/bin/pl index b07e70503..21c44ce9a 100755 --- a/bin/pl +++ b/bin/pl @@ -44,6 +44,9 @@ do_action() { "browser") x-www-browser $@ ;; + "ssh") + ssh -i $2 $1 + ;; *) echo "Unknown action: ${verb}" exit 1 @@ -63,28 +66,22 @@ if [[ "$1" == "open-item" ]]; then DEFAULT_FORMAT="action" fi +if [[ "$1" == "ssh-item" ]]; then + DEFAULT_FORMAT="action" +fi + if [[ "$DEFAULT_FORMAT" == "" ]]; then DEFAULT_FORMAT="raw" fi # By default, we won't use nailgun (for easier setup) -if [[ "${USE_NAILGUN}" == "" ]]; then - USE_NAILGUN=0 -fi - -if [[ "${USE_NAILGUN}" == "1" ]]; then - NAILGUN=ng-nailgun +if [[ "${NAILGUN}" != "" ]]; then if ! builtin type -p ${NAILGUN} &>/dev/null; then - NAILGUN=ng - if ! builtin type -p ${NAILGUN} &>/dev/null; then - NAILGUN=${BASEDIR}/../nailgun/ng - if ! builtin type -p ${NAILGUN} &>/dev/null; then - echo "${NAILGUN} not found; try sudo apt-get install nailgun" - exit 1 - fi - fi + echo "NAILGUN=${NAILGUN}, but ${NAILGUN} not found" + exit 1 fi + USE_NAILGUN=1 fi @@ -113,6 +110,8 @@ if [[ "${USE_NAILGUN}" == "1" ]]; then cmd=(${NAILGUN} org.platformlayer.client.cli.PlatformLayerCli) args=(--format "${FORMAT}" --config -) + + ${NAILGUN} bootstrap ${JAVA} -jar ${BASEDIR}/platformlayer-cli-standalone.jar --listen=${NAILGUN_PORT} & else cmd=(${JAVA} -jar ${BASEDIR}/platformlayer-cli-standalone.jar) args=(--format "${FORMAT}" --config "${CONFIG_FILE}") @@ -125,6 +124,7 @@ if [[ "${FORMAT}" == "action" ]]; then else action=`${cmd[@]} ${args[@]} "${@}"` fi + #echo "ACTION=${action}" do_action ${action} else if [[ "${USE_NAILGUN}" == "1" ]]; then diff --git a/bin/updateschemas.sh b/bin/updateschemas.sh index ecd874c17..ca7274046 100755 --- a/bin/updateschemas.sh +++ b/bin/updateschemas.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash -x set -e @@ -9,61 +9,51 @@ mvn dependency:build-classpath -Dmdep.outputFile=target/classpath.def mvn compile --projects xaas/core,shared/core-model,shared/codegen-annotations # Generate the schema files -mvn generate-resources - -for servicedir in $( find services/ -maxdepth 1 -type d -name 'service-*' | sort ) -#for servicedir in "services/service-cloud-lxc" -do -service=`basename ${servicedir}` -echo "Processing ${service}" - -#mvn compile --projects ${servicedir} - -CORE_FILES=$( find shared/core-model/src/main/java -type f -name '*.java' | grep core | xargs grep -l "@Xml" ) -MODEL_FILES=$( find ${servicedir}/src/main/java -type f -name '*.java' | xargs grep -l "@Xml" ) -CLASSPATH=`cat ${servicedir}/target/classpath.def` -CLASSPATH=${CLASSPATH}:${servicedir}/target/classes -#shared/codegen-annotations/target/classes:xaas/core/target/classes:shared/core-model/target/classes:/home/justinsb/.m2/repository/com/google/guava/guava/10.0.1/guava-10.0.1.jar:${servicedir}/target/classes -OUTDIR=${servicedir}/target/schemas -mkdir -p ${OUTDIR} - -echo "Doing schemagen..." -#mvn generate-resources -#schemagen -d ${OUTDIR} -cp ${CLASSPATH} ${CORE_FILES} ${MODEL_FILES} -done - - -#for service in services/*; do -#echo ${service} -#done +mvn generate-resources --projects xaas/core,shared/core-model,shared/codegen-annotations -#schemagen shared/core-model/src/main/java/org/platformlayer/core/model/*.java services/service-cloud-lxc/src/main/java/org/openstack/service/lxc/model/*.java # Copy the schemas from the target directories +pushd schemas +#cp ../shared/core-model/target/generated-resources/schemagen/schema1.xsd platformlayer-instancesupervisor.xsd +#cp ../shared/core-model/target/generated-resources/schemagen/schema2.xsd platformlayer-imagefactory.xsd +#cp ../shared/core-model/target/generated-resources/schemagen/schema3.xsd platformlayer-dns.xsd +#cp ../shared/core-model/target/generated-resources/schemagen/schema4.xsd platformlayer-metrics.xsd +#cp ../shared/core-model/target/generated-resources/schemagen/schema5.xsd platformlayer-jobs.xsd +#cp ../shared/core-model/target/generated-resources/schemagen/schema6.xsd platformlayer-core.xsd + +#find *.xsd -name "platformlayer-*.xsd" | xargs sed -i 's/schema1.xsd/platformlayer-instancesupervisor.xsd/g' +#find *.xsd -name "platformlayer-*.xsd" | xargs sed -i 's/schema2.xsd/platformlayer-imagefactory.xsd/g' +#find *.xsd -name "platformlayer-*.xsd" | xargs sed -i 's/schema3.xsd/platformlayer-dns.xsd/g' +#find *.xsd -name "platformlayer-*.xsd" | xargs sed -i 's/schema4.xsd/platformlayer-metrics.xsd/g' +#find *.xsd -name "platformlayer-*.xsd" | xargs sed -i 's/schema5.xsd/platformlayer-jobs.xsd/g' +#find *.xsd -name "platformlayer-*.xsd" | xargs sed -i 's/schema6.xsd/platformlayer-core.xsd/g' +popd +mvn generate-resources pushd schemas -cp ../shared/core-model/target/schemas/*.xsd . - cp ../services/service-federation/target/generated-resources/schemagen/schema1.xsd federation.xsd -cp ../services/service-apt-cache/target/generated-resources/schemagen/schema1.xsd apt-cache.xsd cp ../services/service-dns/target/generated-resources/schemagen/schema1.xsd dns.xsd cp ../services/service-dnsresolver/target/generated-resources/schemagen/schema1.xsd dnsresolver.xsd -cp ../services/service-image-factory/target/generated-resources/schemagen/schema1.xsd image-factory.xsd -cp ../services/service-instance-supervisor/target/generated-resources/schemagen/schema1.xsd instance-supervisor.xsd -cp ../services/service-collectd/target/generated-resources/schemagen/schema1.xsd collectd.xsd -cp ../services/service-networks/target/generated-resources/schemagen/schema1.xsd networks.xsd -cp ../services/service-image-store/target/generated-resources/schemagen/schema1.xsd image-store.xsd -cp ../services/service-cloud-lxc/target/generated-resources/schemagen/schema1.xsd machines-lxc.xsd -cp ../services/service-cloud-raw/target/generated-resources/schemagen/schema1.xsd machines-raw.xsd -cp ../services/service-cloud-openstack/target/generated-resources/schemagen/schema1.xsd machines-openstack.xsd - +#cp ../services/service-image-factory/target/generated-resources/schemagen/schema1.xsd image-factory.xsd +#cp ../services/service-instance-supervisor/target/generated-resources/schemagen/schema1.xsd instance-supervisor.xsd +#cp ../services/service-collectd/target/generated-resources/schemagen/schema1.xsd collectd.xsd +#cp ../services/service-networks/target/generated-resources/schemagen/schema1.xsd networks.xsd +#cp ../services/service-image-store/target/generated-resources/schemagen/schema1.xsd image-store.xsd +#cp ../services/service-cloud-lxc/target/generated-resources/schemagen/schema1.xsd machines-lxc.xsd +#cp ../services/service-cloud-raw/target/generated-resources/schemagen/schema1.xsd machines-raw.xsd +#cp ../services/service-cloud-openstack/target/generated-resources/schemagen/schema1.xsd machines-openstack.xsd + +# TODO: Yuk... it would be good to fix this up properly #find *.xsd ! -name "platformlayer-*.xsd" | xargs sed -i 's/schema1.xsd/platformlayer-core.xsd/g' find *.xsd ! -name "platformlayer-*.xsd" | xargs sed -i 's/schema2.xsd/platformlayer-core.xsd/g' +find *.xsd ! -name "platformlayer-*.xsd" | xargs sed -i 's/schema3.xsd/platformlayer-core.xsd/g' #find *.xsd ! -name "platformlayer-*.xsd" | xargs sed -i 's/schemaLocation=.schema..xsd.//g' popd # Update the bindings to the schema files mvn generate-resources - +pushd ../bindings/platformlayer-api +mvn jaxb2:generate +popd diff --git a/bindings/cli/PlatformLayer CLI Server.launch b/bindings/cli/PlatformLayer CLI Server.launch deleted file mode 100644 index 102a9a2c2..000000000 --- a/bindings/cli/PlatformLayer CLI Server.launch +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/bindings/cli/PlatformLayer CLI.launch b/bindings/cli/PlatformLayer CLI.launch deleted file mode 100644 index ef06f842c..000000000 --- a/bindings/cli/PlatformLayer CLI.launch +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/auth/server-user/src/main/resources/log4j.properties b/bindings/cli/log4j.properties similarity index 100% rename from auth/server-user/src/main/resources/log4j.properties rename to bindings/cli/log4j.properties diff --git a/bindings/cli/pom.xml b/bindings/cli/pom.xml index 7746d3d53..b92276de6 100644 --- a/bindings/cli/pom.xml +++ b/bindings/cli/pom.xml @@ -1,86 +1,154 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + 4.0.0 - - org.platformlayer - platformlayer-bindings-parent - 1.0-SNAPSHOT - + + org.platformlayer + platformlayer-bindings-parent + 1.0-SNAPSHOT + - platformlayer-bindings-cli - PlatformLayer :: Bindings :: Command line client + platformlayer-bindings-cli + PlatformLayer :: Bindings :: Command line client - - - org.platformlayer - platformlayer-api - + + + org.apache.httpcomponents + httpclient + org.platformlayer - shared-cli + platformlayer-api + + + + com.fathomdb + fathomdb-cli - - org.slf4j - slf4j-log4j12 - - - - - org.python - jython - 2.5.0 - - - - - - - org.apache.maven.plugins - maven-shade-plugin - 1.4 - - - package - - shade - - - - - org.platformlayer.client.cli.PlatformLayerCli - - - META-INF/services/javax.ws.rs.ext.MessageBodyReader - - - META-INF/services/javax.ws.rs.ext.MessageBodyWriter - - - - target/platformlayer-cli-standalone.jar - - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - - - + + com.fathomdb + fathomdb-http + + + + com.fathomdb + fathomdb-crypto + + + + org.slf4j + slf4j-simple + + + + org.json + json + + + + com.fasterxml.jackson.core + jackson-core + + + + com.fasterxml.jackson.core + jackson-annotations + + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + + + + com.fasterxml.jackson.core + jackson-databind + + + + org.codehaus.jettison + jettison + + + + javax.xml.bind + jaxb-api + + + + + + EclipseLink + http://download.eclipse.org/rt/eclipselink/maven.repo + + + + + + + eu.somatik.serviceloader-maven-plugin + serviceloader-maven-plugin + 1.0.2 + + + com.fathomdb.cli.commands.CommandRunner + com.fathomdb.cli.formatter.Formatter + + + + + + generate + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 1.4 + + + package + + shade + + + + + org.platformlayer.client.cli.PlatformLayerCli + + + META-INF/services/javax.ws.rs.ext.MessageBodyReader + + + META-INF/services/javax.ws.rs.ext.MessageBodyWriter + + + + target/platformlayer-cli-standalone.jar + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + + diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/ConfigurationOptions.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/ConfigurationOptions.java index 7135dff92..ebda04f4e 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/ConfigurationOptions.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/ConfigurationOptions.java @@ -1,28 +1,45 @@ package org.platformlayer.client.cli; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.io.PrintStream; import java.util.Properties; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import org.kohsuke.args4j.Option; -import org.openstack.utils.Io; -import org.openstack.utils.NoCloseInputStream; -import org.platformlayer.DirectPlatformLayerClient; -import org.platformlayer.IoUtils; +import org.platformlayer.HttpPlatformLayerClient; import org.platformlayer.PlatformLayerClient; +import org.platformlayer.http.HttpStrategy; +import org.platformlayer.http.jre.JreHttpStrategy; import org.platformlayer.ops.OpsException; +import com.fathomdb.cli.CliException; import com.fathomdb.cli.CliOptions; +import com.fathomdb.io.IoUtils; +import com.fathomdb.io.NoCloseInputStream; +import com.fathomdb.properties.PropertyUtils; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.io.Closeables; public class ConfigurationOptions extends CliOptions { @Option(name = "-c", aliases = "--config", usage = "config file", required = true) String configFile; + @Option(name = "-debug", aliases = "--debug", usage = "enable debug output") + boolean debug; + + static final Cache platformLayerClientCache = CacheBuilder.newBuilder() + .expireAfterAccess(300, TimeUnit.SECONDS).maximumSize(10).build(); + public PlatformLayerClient buildPlatformLayerClient() throws IOException, OpsException { - PlatformLayerClient client; + HttpPlatformLayerClient client; if (configFile == null) { throw new IllegalArgumentException("Config file is required"); } @@ -31,13 +48,13 @@ public PlatformLayerClient buildPlatformLayerClient() throws IOException, OpsExc try { if (configFile.equals("-")) { // Read from stdin - // Don't auto-close it, and that terminates nailgun + // Don't auto-close it: that terminates nailgun is = new NoCloseInputStream(System.in); } else { if (isServerMode()) { throw new IllegalArgumentException("Must pass config file over stdin in server mode"); } - File file = Io.resolve(configFile); + File file = IoUtils.resolve(configFile); if (!file.exists()) { throw new FileNotFoundException("Configuration file not found: " + file); } @@ -45,22 +62,57 @@ public PlatformLayerClient buildPlatformLayerClient() throws IOException, OpsExc is = new FileInputStream(file); } - Properties properties = new Properties(); + final Properties properties = new Properties(); try { properties.load(is); } catch (IOException e) { throw new IOException("Error reading configuration file", e); } - client = DirectPlatformLayerClient.buildUsingProperties(properties); - // client = FederatedPlatformLayerClient.buildUsingConfig(is); + if (properties.getProperty("platformlayer.username") == null) { + throw new CliException("User property not set in configuration file"); + } + + if (debug) { + client = buildPlatformLayerClient(properties, debug); + } else { + String propertiesKey = PropertyUtils.serialize(properties); + + try { + client = platformLayerClientCache.get(propertiesKey, new Callable() { + @Override + public HttpPlatformLayerClient call() throws Exception { + return buildPlatformLayerClient(properties, false); + } + }); + } catch (ExecutionException e) { + throw new CliException("Error building platformlayer client", e); + } + } } finally { if (is != System.in) { - IoUtils.safeClose(is); + Closeables.closeQuietly(is); } } return client; } + private HttpPlatformLayerClient buildPlatformLayerClient(Properties properties, boolean debug) { + HttpStrategy httpStrategy = new JreHttpStrategy(); + // HttpStrategy httpStrategy = new ApacheCommonsHttpStrategy(); + HttpPlatformLayerClient client = HttpPlatformLayerClient.buildUsingProperties(httpStrategy, properties); + + if (debug) { + client.setDebug(System.err); + } else { + // We don't want debug messages to interfere with our output + // TODO: Fix this so debug output doesn't interfere (stderr?) + // TODO: Maybe output the debug info only in case of failure? + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + client.setDebug(new PrintStream(baos)); + } + + return client; + } } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/PlatformLayerCli.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/PlatformLayerCli.java index 2378e7361..933b9a859 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/PlatformLayerCli.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/PlatformLayerCli.java @@ -2,7 +2,7 @@ import org.kohsuke.args4j.CmdLineParser; import org.platformlayer.client.cli.commands.PlatformLayerCommandRegistry; -import org.platformlayer.client.cli.model.ConfigureAction; +import org.platformlayer.client.cli.model.CliAction; import org.platformlayer.client.cli.model.ItemPath; import com.fathomdb.cli.CliBase; @@ -33,13 +33,15 @@ public CommandRegistry buildCommandRegistry() { } static { - CmdLineParser.registerHandler(ConfigureAction.class, StringWrapperOptionHandler.class); + CmdLineParser.registerHandler(CliAction.class, StringWrapperOptionHandler.class); CmdLineParser.registerHandler(ItemPath.class, StringWrapperOptionHandler.class); init(new PlatformLayerCliHandler()); } public static void main(String[] args) { + // System.setProperty("javax.xml.bind.context.factory", + // org.eclipse.persistence.jaxb.JAXBContextFactory.class.getName()); CliBase.main(args); } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/PlatformLayerCliContext.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/PlatformLayerCliContext.java index 7c145f723..a4721aed0 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/PlatformLayerCliContext.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/PlatformLayerCliContext.java @@ -77,14 +77,14 @@ public Multimap listItemTypes() throws PlatformLayerClientE Iterable allServices = getAllServiceInfos(); Multimap items = HashMultimap.create(); for (ServiceInfo service : allServices) { - for (String itemType : service.getPublicTypes()) { + for (String itemType : service.getItemTypes()) { items.put(itemType, service); } } return items; } - public PlatformLayerKey pathToItem(String path) throws PlatformLayerClientException { + public PlatformLayerKey pathToItem(ProjectId project, String path) throws PlatformLayerClientException { String serviceType = null; String itemType = null; String itemId = null; @@ -138,14 +138,25 @@ public PlatformLayerKey pathToItem(String path) throws PlatformLayerClientExcept itemId = Joiner.on('/').join(components); - if (serviceType == null || itemType == null || Strings.isNullOrEmpty(itemId)) { - throw new IllegalArgumentException("Cannot resolve path: " + path); + if (serviceType == null) { + throw new IllegalArgumentException("Cannot resolve path (service type not resolved): " + path); + } + + if (itemType == null) { + throw new IllegalArgumentException("Cannot resolve path (item type not resolved): " + path); + } + + if (Strings.isNullOrEmpty(itemId)) { + throw new IllegalArgumentException("Cannot resolve path (item id not resolved): " + path); } FederationKey host = null; - ProjectId project = null; return new PlatformLayerKey(host, project, new ServiceType(serviceType), new ItemType(itemType), new ManagedItemId(itemId)); } + public ProjectId getProject() { + return getPlatformLayerClient().getProject(); + } + } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/autocomplete/AutoCompleteJobId.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/autocomplete/AutoCompleteJobId.java index 6d36808ad..c3ff44f78 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/autocomplete/AutoCompleteJobId.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/autocomplete/AutoCompleteJobId.java @@ -12,13 +12,11 @@ public class AutoCompleteJobId extends PlatformLayerSimpleAutoCompleter { @Override public List doComplete(CliContext context, String prefix) throws Exception { PlatformLayerClient client = getPlatformLayerClient(context); - Iterable jobDatas = client.listJobs(); List jobs = Lists.newArrayList(); - for (JobData jobData : jobDatas) { - jobs.add(jobData.key.getItemId().getKey()); + for (JobData jobData : client.listJobs().getJobs()) { + jobs.add(jobData.getJobId()); } addSuffix(jobs, " "); return jobs; } - } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/autocomplete/PlatformLayerSimpleAutoCompleter.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/autocomplete/PlatformLayerSimpleAutoCompleter.java index 5bd0b685a..86a97bcb7 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/autocomplete/PlatformLayerSimpleAutoCompleter.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/autocomplete/PlatformLayerSimpleAutoCompleter.java @@ -4,9 +4,9 @@ import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientException; -import org.platformlayer.UntypedItem; import org.platformlayer.client.cli.PlatformLayerCliContext; import org.platformlayer.client.cli.commands.PlatformLayerCommandRunnerBase; +import org.platformlayer.common.UntypedItem; import org.platformlayer.core.model.PlatformLayerKey; import com.fathomdb.cli.CliContext; @@ -24,8 +24,8 @@ protected List listItems(CliContext context, String itemType) throws Pla PlatformLayerKey key = PlatformLayerCommandRunnerBase.pathToKey(client, itemType); List items = Lists.newArrayList(); - for (UntypedItem item : client.listItemsUntyped(key)) { - items.add(item.getPlatformLayerKey().getItemId().getKey()); + for (UntypedItem item : client.listItemsUntyped(key).getItems()) { + items.add(item.getKey().getItemId().getKey()); } return items; } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ActionCommandBase.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ActionCommandBase.java new file mode 100644 index 000000000..1b61fda94 --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ActionCommandBase.java @@ -0,0 +1,33 @@ +package org.platformlayer.client.cli.commands; + +import java.io.PrintWriter; + +import org.platformlayer.PlatformLayerClient; +import org.platformlayer.PlatformLayerClientException; +import org.platformlayer.client.cli.model.ItemPath; +import org.platformlayer.core.model.Action; +import org.platformlayer.core.model.PlatformLayerKey; +import org.platformlayer.jobs.model.JobData; + +public abstract class ActionCommandBase extends PlatformLayerCommandRunnerBase { + + protected ActionCommandBase(String verb) { + super(verb, "item"); + } + + protected JobData runAction(ItemPath path, Action action) throws PlatformLayerClientException { + PlatformLayerClient client = getPlatformLayerClient(); + + PlatformLayerKey key = path.resolve(getContext()); + + JobData ret = client.doAction(key, action); + return ret; + } + + @Override + public void formatRaw(Object o, PrintWriter writer) { + JobData jobData = (JobData) o; + writer.println(jobData.getJobId()); + } + +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/AddConfig.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/AddConfig.java new file mode 100644 index 000000000..5bd9beb23 --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/AddConfig.java @@ -0,0 +1,68 @@ +package org.platformlayer.client.cli.commands; + +import org.kohsuke.args4j.Argument; +import org.platformlayer.PlatformLayerClientException; +import org.platformlayer.UntypedItemXml; +import org.platformlayer.client.cli.model.ItemPath; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import com.fathomdb.cli.CliException; + +public class AddConfig extends ItemMutatorCommand { + + @Argument(index = 0, required = true, metaVar = "path") + public ItemPath path; + + @Argument(index = 1, required = true, metaVar = "property") + public String property; + + @Argument(index = 2, required = true, metaVar = "key") + public String key; + + @Argument(index = 3, required = true, metaVar = "value") + public String value; + + public AddConfig() { + super("add", "config"); + } + + @Override + public Object runCommand() throws PlatformLayerClientException { + UntypedItemXml item = runCommand(path); + return item; + } + + @Override + protected void changeItem(UntypedItemXml item) { + Element element = getElement(item, property); + if (element == null) { + throw new CliException("Cannot find element: " + property); + } + + String namespaceURI = element.getNamespaceURI(); + String localName = element.getLocalName(); + + Node parentNode = element.getParentNode(); + String parentNamespaceUri = parentNode.getNamespaceURI(); + String parentTag = parentNode.getLocalName(); + + String pathKey = parentNamespaceUri + ":" + parentTag + ":" + namespaceURI + ":" + localName; + + if ("http://platformlayer.org/service/platformlayer/v1.0:platformLayerService:http://platformlayer.org/service/platformlayer/v1.0:config" + .equals(pathKey)) { + Element newNode = element.getOwnerDocument().createElementNS(NAMESPACE_URI_CORE, "property"); + Element keyNode = element.getOwnerDocument().createElementNS(NAMESPACE_URI_CORE, "key"); + keyNode.setTextContent(key); + Element valueNode = element.getOwnerDocument().createElementNS(NAMESPACE_URI_CORE, "value"); + valueNode.setTextContent(value); + newNode.appendChild(keyNode); + newNode.appendChild(valueNode); + + element.appendChild(newNode); + } else { + throw new UnsupportedOperationException(); + } + } + +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/AddTag.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/AddTag.java new file mode 100644 index 000000000..72392f733 --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/AddTag.java @@ -0,0 +1,47 @@ +package org.platformlayer.client.cli.commands; + +import java.io.PrintWriter; + +import org.kohsuke.args4j.Argument; +import org.platformlayer.PlatformLayerClient; +import org.platformlayer.PlatformLayerClientException; +import org.platformlayer.client.cli.model.ItemPath; +import org.platformlayer.core.model.PlatformLayerKey; +import org.platformlayer.core.model.Tag; +import org.platformlayer.core.model.TagChanges; +import org.platformlayer.core.model.Tags; + +public class AddTag extends PlatformLayerCommandRunnerBase { + @Argument(index = 0, required = true, metaVar = "path") + public ItemPath path; + + @Argument(index = 1, required = true, metaVar = "key") + public String tagKey; + @Argument(index = 2, required = true, metaVar = "value") + public String tagValue; + + public AddTag() { + super("add", "tag"); + } + + @Override + public Object runCommand() throws PlatformLayerClientException { + PlatformLayerClient client = getPlatformLayerClient(); + + PlatformLayerKey resolved = path.resolve(getContext()); + + TagChanges tagChanges = new TagChanges(); + Tag tag = Tag.build(tagKey, tagValue); + tagChanges.addTags.add(tag); + + return client.changeTags(resolved, tagChanges, null); + } + + @Override + public void formatRaw(Object o, PrintWriter writer) { + Tags tags = (Tags) o; + for (Tag tag : tags.tags) { + writer.println(tag.getKey() + "\t" + tag.getValue()); + } + } +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/BackupItem.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/BackupItem.java new file mode 100644 index 000000000..19ab296d1 --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/BackupItem.java @@ -0,0 +1,21 @@ +package org.platformlayer.client.cli.commands; + +import org.kohsuke.args4j.Argument; +import org.platformlayer.PlatformLayerClientException; +import org.platformlayer.client.cli.model.ItemPath; +import org.platformlayer.core.model.BackupAction; + +public class BackupItem extends ActionCommandBase { + @Argument(index = 0, usage = "path", required = true) + public ItemPath path; + + public BackupItem() { + super("backup"); + } + + @Override + public Object runCommand() throws PlatformLayerClientException { + BackupAction action = new BackupAction(); + return runAction(path, action); + } +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ConfigureItem.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ConfigureItem.java new file mode 100644 index 000000000..6d13461a1 --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ConfigureItem.java @@ -0,0 +1,22 @@ +package org.platformlayer.client.cli.commands; + +import org.kohsuke.args4j.Argument; +import org.platformlayer.PlatformLayerClientException; +import org.platformlayer.client.cli.model.ItemPath; +import org.platformlayer.core.model.ConfigureAction; + +public class ConfigureItem extends ActionCommandBase { + @Argument(index = 0, usage = "path", required = true) + public ItemPath path; + + public ConfigureItem() { + super("configure"); + } + + @Override + public Object runCommand() throws PlatformLayerClientException { + ConfigureAction action = new ConfigureAction(); + return runAction(path, action); + } + +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/CreateItem.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/CreateItem.java deleted file mode 100644 index 6f7444edb..000000000 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/CreateItem.java +++ /dev/null @@ -1,56 +0,0 @@ -//package org.platformlayer.client.cli.commands; -// -//import java.io.PrintWriter; -// -//import org.codehaus.jettison.json.JSONException; -//import org.codehaus.jettison.json.JSONObject; -//import org.kohsuke.args4j.Argument; -//import org.platformlayer.Format; -//import org.platformlayer.PlatformLayerClient; -//import org.platformlayer.PlatformLayerClientException; -//import org.platformlayer.client.cli.autocomplete.AutoCompleteItemType; -//import org.platformlayer.core.model.PlatformLayerKey; -// -//import com.fathomdb.cli.autocomplete.AutoCompletor; -//import com.fathomdb.cli.autocomplete.SimpleAutoCompleter; -// -//public class CreateItem extends PlatformLayerCommandRunnerBase { -// @Argument(index = 0) -// public String path; -// -// @Argument(index = 1) -// public String json; -// -// public CreateItem() { -// super("create", "item"); -// } -// -// @Override -// public Object runCommand() throws PlatformLayerClientException, JSONException { -// PlatformLayerClient client = getPlatformLayerClient(); -// -// PlatformLayerKey key = pathToKey(client, path); -// -// String wrapper = "{ \"" + key.getItemType().getKey() + "\": " + json + " }"; -// String retvalJsonString = client.createItem(key.getServiceType(), key.getItemType(), wrapper, Format.JSON); -// JSONObject retvalJsonObject = new JSONObject(retvalJsonString); -// -// return retvalJsonObject; -// } -// -// @Override -// public AutoCompletor getAutoCompleter() { -// return new SimpleAutoCompleter(new AutoCompleteItemType(), null); -// } -// -// @Override -// public void formatRaw(Object o, PrintWriter writer) { -// JSONObject json = (JSONObject) o; -// try { -// writer.println(json.getString("id")); -// } catch (JSONException e) { -// throw new IllegalArgumentException("id property not found"); -// } -// } -// -// } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/DeleteItem.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/DeleteItem.java index 04b733faf..7925794d4 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/DeleteItem.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/DeleteItem.java @@ -1,11 +1,13 @@ package org.platformlayer.client.cli.commands; -import org.codehaus.jettison.json.JSONException; +import java.io.PrintWriter; + import org.kohsuke.args4j.Argument; import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientException; import org.platformlayer.client.cli.model.ItemPath; import org.platformlayer.core.model.PlatformLayerKey; +import org.platformlayer.jobs.model.JobData; public class DeleteItem extends PlatformLayerCommandRunnerBase { @Argument(index = 0) @@ -16,13 +18,18 @@ public DeleteItem() { } @Override - public Object runCommand() throws PlatformLayerClientException, JSONException { + public Object runCommand() throws PlatformLayerClientException { PlatformLayerClient client = getPlatformLayerClient(); PlatformLayerKey key = path.resolve(getContext()); - client.deleteItem(key); - return key.getItemId().getKey(); + JobData jobData = client.deleteItem(key); + return jobData; } + @Override + public void formatRaw(Object o, PrintWriter writer) { + JobData jobData = (JobData) o; + writer.println(jobData.getJobId()); + } } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/DeleteLink.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/DeleteLink.java new file mode 100644 index 000000000..3715b6ec2 --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/DeleteLink.java @@ -0,0 +1,62 @@ +package org.platformlayer.client.cli.commands; + +import java.io.PrintWriter; +import java.util.Collection; +import java.util.List; + +import org.kohsuke.args4j.Argument; +import org.platformlayer.Format; +import org.platformlayer.PlatformLayerClient; +import org.platformlayer.PlatformLayerClientException; +import org.platformlayer.UntypedItemXml; +import org.platformlayer.client.cli.model.ItemPath; +import org.platformlayer.core.model.Link; +import org.platformlayer.core.model.Links; +import org.platformlayer.core.model.PlatformLayerKey; + +public class DeleteLink extends PlatformLayerCommandRunnerBase { + @Argument(index = 0, required = true, metaVar = "path") + public ItemPath path; + + @Argument(index = 1, required = true, metaVar = "name") + public String name; + + public DeleteLink() { + super("delete", "link"); + } + + @Override + public Object runCommand() throws PlatformLayerClientException { + PlatformLayerClient client = getPlatformLayerClient(); + + PlatformLayerKey resolved = path.resolve(getContext()); + + UntypedItemXml item = (UntypedItemXml) client.getItemUntyped(resolved, Format.XML); + + Links links = item.getLinks(); + + Link existing = links.findLink(name); + List linkList = links.getLinks(); + if (existing != null) { + linkList.remove(existing); + + item.setLinks(links); + + String xml = item.serialize(); + + UntypedItemXml updated = (UntypedItemXml) client.putItem(resolved, xml, Format.XML); + + return updated.getLinks().getLinks(); + } else { + return linkList; + } + } + + @Override + public void formatRaw(Object o, PrintWriter writer) { + Collection links = (Collection) o; + for (Link link : links) { + writer.println(link.getName() + "\t" + link.getTarget()); + } + } +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/DeleteTag.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/DeleteTag.java index 22a2ba8f5..4f7b6f4cd 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/DeleteTag.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/DeleteTag.java @@ -1,10 +1,11 @@ package org.platformlayer.client.cli.commands; import org.kohsuke.args4j.Argument; +import org.platformlayer.Format; import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientException; -import org.platformlayer.UntypedItem; import org.platformlayer.client.cli.model.ItemPath; +import org.platformlayer.common.UntypedItem; import org.platformlayer.core.model.PlatformLayerKey; import org.platformlayer.core.model.Tag; import org.platformlayer.core.model.TagChanges; @@ -29,7 +30,7 @@ public Object runCommand() throws PlatformLayerClientException { PlatformLayerClient client = getPlatformLayerClient(); PlatformLayerKey key = path.resolve(getContext()); - UntypedItem ret = client.getItemUntyped(key); + UntypedItem ret = client.getItemUntyped(key, Format.XML); TagChanges tagChanges = new TagChanges(); for (Tag tag : ret.getTags()) { @@ -44,7 +45,7 @@ public Object runCommand() throws PlatformLayerClientException { tagChanges.removeTags.add(tag); } - Tags newTags = client.changeTags(key, tagChanges); + Tags newTags = client.changeTags(key, tagChanges, null); return newTags; } } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/DoAction.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/DoAction.java index 53a97b4b3..61556158b 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/DoAction.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/DoAction.java @@ -2,20 +2,26 @@ import java.io.PrintWriter; +import org.json.JSONException; +import org.json.JSONObject; import org.kohsuke.args4j.Argument; +import org.platformlayer.Format; import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientException; -import org.platformlayer.client.cli.model.ConfigureAction; +import org.platformlayer.client.cli.model.CliAction; import org.platformlayer.client.cli.model.ItemPath; import org.platformlayer.core.model.PlatformLayerKey; import org.platformlayer.jobs.model.JobData; public class DoAction extends PlatformLayerCommandRunnerBase { - @Argument(index = 0) + @Argument(index = 0, usage = "path", required = true) public ItemPath path; - @Argument(index = 1) - public ConfigureAction action; + @Argument(index = 1, usage = "action", required = true) + public CliAction action; + + @Argument(index = 2, usage = "data", required = false) + public String json; public DoAction() { super("do", "action"); @@ -23,19 +29,34 @@ public DoAction() { @Override public Object runCommand() throws PlatformLayerClientException { + String json; + + try { + JSONObject data; + if (this.json != null) { + data = new JSONObject(this.json); + } else { + data = new JSONObject(); + } + data.put("type", action.getKey()); + + json = data.toString(); + } catch (JSONException e) { + throw new IllegalStateException("Error building JSON", e); + } + PlatformLayerClient client = getPlatformLayerClient(); PlatformLayerKey key = path.resolve(getContext()); - Object ret = client.doAction(key, action.getKey()); - + JobData ret = client.doAction(key, json, Format.JSON); return ret; } @Override public void formatRaw(Object o, PrintWriter writer) { JobData jobData = (JobData) o; - writer.println(jobData.key); + writer.println(jobData.getJobId()); } } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetEndpoint.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetEndpoint.java index cd1883ef5..75dedf23c 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetEndpoint.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetEndpoint.java @@ -4,11 +4,12 @@ import java.util.List; import org.kohsuke.args4j.Argument; -import org.platformlayer.EndpointInfo; +import org.platformlayer.Format; import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientException; -import org.platformlayer.UntypedItem; import org.platformlayer.client.cli.model.ItemPath; +import org.platformlayer.common.UntypedItem; +import org.platformlayer.core.model.EndpointInfo; import org.platformlayer.core.model.PlatformLayerKey; public class GetEndpoint extends PlatformLayerCommandRunnerBase { @@ -26,7 +27,7 @@ public Object runCommand() throws PlatformLayerClientException { PlatformLayerKey key = path.resolve(getContext()); - UntypedItem untypedItem = client.getItemUntyped(key); + UntypedItem untypedItem = client.getItemUntyped(key, Format.XML); List endpoints = EndpointInfo.getEndpoints(untypedItem.getTags()); return endpoints; diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetItem.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetItem.java index ba06183c4..23d6e0800 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetItem.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetItem.java @@ -1,20 +1,10 @@ package org.platformlayer.client.cli.commands; -import java.io.PrintWriter; - -import javax.xml.transform.Source; -import javax.xml.transform.TransformerException; -import javax.xml.transform.dom.DOMSource; - import org.kohsuke.args4j.Argument; import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientException; -import org.platformlayer.UntypedItem; import org.platformlayer.client.cli.model.ItemPath; import org.platformlayer.core.model.PlatformLayerKey; -import org.platformlayer.xml.XmlHelper; - -import com.fathomdb.cli.commands.Ansi; public class GetItem extends PlatformLayerCommandRunnerBase { @Argument(index = 0) @@ -29,26 +19,7 @@ public Object runCommand() throws PlatformLayerClientException { PlatformLayerClient client = getPlatformLayerClient(); PlatformLayerKey key = path.resolve(getContext()); - return client.getItemUntyped(key); - } - - @Override - public void formatRaw(Object o, PrintWriter writer) { - Ansi ansi = new Ansi(writer); - - UntypedItem item = (UntypedItem) o; - - String xml; - try { - Source src = new DOMSource(item.getRoot()); - xml = XmlHelper.toXml(src, 4); - } catch (TransformerException e) { - throw new IllegalStateException("Error serializing data", e); - } - - ansi.println(xml); - - ansi.reset(); + return client.getItemUntyped(key, getFormat()); } } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetJobLog.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetJobLog.java index 4d1fbeb58..c313f9d0d 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetJobLog.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetJobLog.java @@ -1,23 +1,30 @@ package org.platformlayer.client.cli.commands; import java.io.PrintWriter; +import java.util.List; -import org.apache.log4j.Priority; import org.kohsuke.args4j.Argument; import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientException; +import org.platformlayer.PlatformLayerClientNotFoundException; import org.platformlayer.client.cli.autocomplete.AutoCompleteJobId; +import org.platformlayer.jobs.model.JobExecutionData; +import org.platformlayer.jobs.model.JobExecutionList; import org.platformlayer.jobs.model.JobLog; -import org.platformlayer.jobs.model.JobLogLine; +import org.platformlayer.jobs.model.JobState; import com.fathomdb.cli.autocomplete.AutoCompletor; import com.fathomdb.cli.autocomplete.SimpleAutoCompleter; -import com.fathomdb.cli.commands.Ansi; +import com.google.common.base.Strings; +import com.google.common.collect.Lists; public class GetJobLog extends PlatformLayerCommandRunnerBase { - @Argument + @Argument(index = 0) String jobId; + @Argument(index = 1) + String executionId; + public GetJobLog() { super("get", "log"); } @@ -26,9 +33,47 @@ public GetJobLog() { public Object runCommand() throws PlatformLayerClientException { PlatformLayerClient client = getPlatformLayerClient(); - JobLog jobLog = client.getJobLog(jobId); + if (jobId.contains("/") && executionId == null) { + String[] tokens = jobId.split("/"); + if (tokens.length == 2) { + jobId = tokens[0]; + executionId = tokens[1]; + } + } + List logs = Lists.newArrayList(); + + if (Strings.isNullOrEmpty(executionId)) { + JobExecutionList jobExecutions = client.listJobExecutions(jobId); + + List runs = jobExecutions.getRuns(); + + sort(runs); + + // TODO: Remove limit (or iterate) + if (runs.size() > 10) { + runs = Lists.newArrayList(runs.subList(runs.size() - 10, runs.size())); + } + + // TODO: Fix 1+N slowness... + for (JobExecutionData execution : runs) { + if (execution.getState() == JobState.PRESTART) { + continue; + } + + String executionId = execution.getExecutionId(); + try { + JobLog jobLog = client.getJobExecutionLog(jobId, executionId); + logs.add(jobLog); + } catch (PlatformLayerClientNotFoundException e) { + // TODO: Warn? + } + } + } else { + JobLog jobLog = client.getJobExecutionLog(jobId, executionId); + logs.add(jobLog); + } - return jobLog; + return logs; } @Override @@ -38,29 +83,12 @@ public AutoCompletor getAutoCompleter() { @Override public void formatRaw(Object o, PrintWriter writer) { - Ansi ansi = new Ansi(writer); - - JobLog jobLog = (JobLog) o; - for (JobLogLine line : jobLog) { - if (line.level >= Priority.ERROR_INT) { - ansi.setColorRed(); - } else if (line.level >= Priority.WARN_INT) { - ansi.setColorYellow(); - } else if (line.level >= Priority.INFO_INT) { - ansi.setColorGreen(); - } else { - ansi.setColorBlue(); - } + JobLogPrinter printer = new JobLogPrinter(writer); + List jobLogs = (List) o; - writer.println(line.message); - if (line.exception != null) { - for (String exceptionLine : line.exception.info) { - writer.println(exceptionLine); - } - } - } + printer.write(jobLogs); - ansi.reset(); + printer.end(); } } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetMetric.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetMetric.java index a1aff1b61..1ff90ccb8 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetMetric.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetMetric.java @@ -1,17 +1,32 @@ package org.platformlayer.client.cli.commands; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.List; + import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.Option; import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientException; -import org.platformlayer.core.model.PlatformLayerKey; -import org.platformlayer.metrics.model.MetricValues; +import org.platformlayer.client.cli.output.MetricToJsonVisitor; +import org.platformlayer.metrics.model.MetricDataStream; +import org.platformlayer.metrics.model.MetricQuery; public class GetMetric extends PlatformLayerCommandRunnerBase { - @Argument(index = 0) + @Argument(index = 0, required = true, usage = "path") public String path; - @Argument(index = 1) - public String metricKey; + // @Argument(index = 1, required = true, usage = "metric key") + // public String metricKey; + + @Option(name = "-where", usage = "Filter for query") + public List filters; + + @Option(name = "-select", usage = "'Columns' to select") + public List projections; + + @Option(name = "-flatten", usage = "Flatten results") + public boolean flatten = false; public GetMetric() { super("get", "metric"); @@ -21,10 +36,34 @@ public GetMetric() { public Object runCommand() throws PlatformLayerClientException { PlatformLayerClient client = getPlatformLayerClient(); - PlatformLayerKey key = getContext().pathToItem(path); + MetricQuery query = new MetricQuery(); + query.item = getContext().pathToItem(getProject(), path); + if (filters != null) { + query.filters.addAll(filters); + } + + if (projections != null) { + query.projections.addAll(projections); + } + + query.setFlatten(flatten); - MetricValues items = client.getMetric(key, metricKey); + MetricDataStream dataStream = client.getMetric(query); - return items; + return dataStream; } + + @Override + public void formatRaw(Object o, PrintWriter writer) { + MetricDataStream dataStream = (MetricDataStream) o; + + try { + MetricToJsonVisitor visitor = new MetricToJsonVisitor(writer); + dataStream.accept(visitor); + visitor.close(); + } catch (IOException e) { + throw new IllegalArgumentException("Error formatting results", e); + } + } + } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetSshKey.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetSshKey.java index e0fc15a78..8768259e5 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetSshKey.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/GetSshKey.java @@ -1,6 +1,5 @@ package org.platformlayer.client.cli.commands; -import org.codehaus.jettison.json.JSONException; import org.kohsuke.args4j.Argument; import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientException; @@ -10,7 +9,7 @@ import com.fathomdb.cli.autocomplete.SimpleAutoCompleter; public class GetSshKey extends PlatformLayerCommandRunnerBase { - @Argument(index = 0) + @Argument(index = 0, required = true, usage = "service type") public String serviceType; public GetSshKey() { @@ -18,7 +17,7 @@ public GetSshKey() { } @Override - public Object runCommand() throws PlatformLayerClientException, JSONException { + public Object runCommand() throws PlatformLayerClientException { PlatformLayerClient client = getPlatformLayerClient(); String sshKey = client.getSshPublicKey(serviceType); diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ItemMutatorCommand.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ItemMutatorCommand.java new file mode 100644 index 000000000..b605925e9 --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ItemMutatorCommand.java @@ -0,0 +1,60 @@ +package org.platformlayer.client.cli.commands; + +import java.util.List; + +import org.platformlayer.Format; +import org.platformlayer.PlatformLayerClient; +import org.platformlayer.PlatformLayerClientException; +import org.platformlayer.UntypedItemXml; +import org.platformlayer.client.cli.model.ItemPath; +import org.platformlayer.core.model.PlatformLayerKey; +import org.platformlayer.xml.XmlHelper; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import com.google.common.base.Splitter; +import com.google.common.collect.Lists; + +public abstract class ItemMutatorCommand extends PlatformLayerCommandRunnerBase { + + public ItemMutatorCommand(String verb, String noun) { + super(verb, noun); + } + + protected UntypedItemXml runCommand(ItemPath path) throws PlatformLayerClientException { + PlatformLayerClient client = getPlatformLayerClient(); + + PlatformLayerKey resolved = path.resolve(getContext()); + + UntypedItemXml item = (UntypedItemXml) client.getItemUntyped(resolved, Format.XML); + + changeItem(item); + + String xml = item.serialize(); + + UntypedItemXml updated = (UntypedItemXml) client.putItem(resolved, xml, Format.XML); + + return updated; + } + + protected abstract void changeItem(UntypedItemXml item); + + protected Element getElement(UntypedItemXml item, String propertyPath) { + Element element = item.getRoot(); + List tokens = Lists.newArrayList(Splitter.on(".").split(propertyPath)); + for (int i = 0; i < tokens.size(); i++) { + String token = tokens.get(i); + Node child = XmlHelper.getChildElement(element, token); + if (child == null) { + if (i == tokens.size() - 1) { + child = element.getOwnerDocument().createElement(token); + element.appendChild(child); + } else { + return null; + } + } + element = (Element) child; + } + return element; + } +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/JobLogPrinter.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/JobLogPrinter.java new file mode 100644 index 000000000..53411c483 --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/JobLogPrinter.java @@ -0,0 +1,106 @@ +package org.platformlayer.client.cli.commands; + +import java.io.PrintWriter; +import java.util.List; + +import org.platformlayer.jobs.model.JobLog; +import org.platformlayer.jobs.model.JobLogExceptionInfo; +import org.platformlayer.jobs.model.JobLogLine; +import org.platformlayer.jobs.model.JobLogLineLevels; + +import com.fathomdb.cli.commands.Ansi; +import com.fathomdb.cli.commands.Ansi.Color; +import com.google.common.base.Strings; + +public class JobLogPrinter { + + private final PrintWriter writer; + private final Ansi ansi; + + int depth; + String indent; + + public JobLogPrinter(PrintWriter writer) { + this.writer = writer; + this.ansi = new Ansi(writer); + } + + public void write(List jobLogs) { + for (JobLog jobLog : jobLogs) { + write(jobLog); + } + + } + + private void write(JobLog jobLog) { + startJobLog(jobLog); + + for (JobLogLine line : jobLog) { + write(line); + } + + endJobLog(jobLog); + } + + private void endJobLog(JobLog jobLog) { + + } + + public void startJobLog(JobLog jobLog) { + depth = 0; + indent = ""; + } + + public void end() { + ansi.reset(); + + flush(); + } + + public void write(JobLogLine line) { + String type = line.getType(); + + if (!Strings.isNullOrEmpty(type)) { + if (type.equals(JobLogLine.TYPE_ENTER_SCOPE)) { + ansi.println(Color.Default, indent + ">>> " + line.message); + depth++; + indent += " "; + } else if (type.equals(JobLogLine.TYPE_EXIT_SCOPE)) { + depth--; + indent = indent.substring(0, depth * 2); + // ansi.println(indent + "<<< " + line.message); + } else { + ansi.println(Color.Red, indent + "??? " + line.message); + } + return; + } + + Ansi.Color color = Ansi.Color.Default; + + if (line.level >= JobLogLineLevels.LEVEL_ERROR) { + color = Ansi.Color.Red; + } else if (line.level >= JobLogLineLevels.LEVEL_WARN) { + color = Ansi.Color.Yellow; + } else if (line.level >= JobLogLineLevels.LEVEL_INFO) { + color = Ansi.Color.Green; + } else { + color = Ansi.Color.Blue; + } + + ansi.println(color, indent + line.message); + + JobLogExceptionInfo exceptionInfo = line.exception; + while (exceptionInfo != null) { + for (String exceptionLine : exceptionInfo.info) { + ansi.println(color, indent + exceptionLine); + } + + exceptionInfo = exceptionInfo.inner; + } + } + + public void flush() { + writer.flush(); + } + +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/JythonToJson.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/JythonToJson.java deleted file mode 100644 index d7ff28319..000000000 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/JythonToJson.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.platformlayer.client.cli.commands; - -import java.util.Map; -import java.util.Map.Entry; - -import org.python.core.PyDictionary; -import org.python.core.PyList; - -public class JythonToJson { - final StringBuilder sb = new StringBuilder(); - - public String getJson() { - return sb.toString(); - } - - public void append(Object item) { - if (item instanceof PyDictionary) { - append((PyDictionary) item); - } else if (item instanceof PyList) { - append((PyList) item); - } else if (item instanceof String) { - sb.append("\""); - sb.append(item.toString()); - sb.append("\""); - } else { - throw new IllegalArgumentException("Unhandled python type: " + item.getClass()); - } - } - - private void append(PyDictionary dict) { - sb.append("{ "); - - int count = 0; - - for (Object entryObj : dict.entrySet()) { - if (count != 0) { - sb.append(","); - } - count++; - - Map.Entry entry = (Entry) entryObj; - Object key = entry.getKey(); - Object value = entry.getValue(); - - sb.append("\""); - sb.append(key.toString()); - sb.append("\": "); - - append(value); - } - sb.append(" }"); - } - - private void append(PyList dict) { - sb.append("[ "); - - int count = 0; - - for (Object item : dict) { - if (count != 0) { - sb.append(","); - } - count++; - - append(item); - } - sb.append(" ]"); - } -} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListChildren.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListChildren.java index e7231d185..eabeaba7b 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListChildren.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListChildren.java @@ -5,9 +5,9 @@ import org.kohsuke.args4j.Argument; import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientException; -import org.platformlayer.UntypedItem; import org.platformlayer.client.cli.model.ItemPath; import org.platformlayer.client.cli.output.UntypedItemFormatter; +import org.platformlayer.common.UntypedItem; import org.platformlayer.core.model.PlatformLayerKey; import com.fathomdb.cli.commands.Ansi; @@ -25,7 +25,8 @@ public Object runCommand() throws PlatformLayerClientException { PlatformLayerClient client = getPlatformLayerClient(); PlatformLayerKey key = path.resolve(getContext()); - return client.listChildren(key); + boolean includeDeleted = true; + return client.listChildren(key, includeDeleted); } @Override diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListItems.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListItems.java index 19d812a8a..4030b00b9 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListItems.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListItems.java @@ -5,9 +5,9 @@ import org.kohsuke.args4j.Argument; import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientException; -import org.platformlayer.UntypedItem; import org.platformlayer.client.cli.autocomplete.AutoCompleteItemType; import org.platformlayer.client.cli.output.UntypedItemFormatter; +import org.platformlayer.common.UntypedItem; import org.platformlayer.core.model.PlatformLayerKey; import com.fathomdb.cli.autocomplete.AutoCompletor; diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListJobExecutions.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListJobExecutions.java new file mode 100644 index 000000000..84222c83c --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListJobExecutions.java @@ -0,0 +1,95 @@ +package org.platformlayer.client.cli.commands; + +import java.io.IOException; +import java.io.PrintWriter; + +import org.kohsuke.args4j.Argument; +import org.platformlayer.PlatformLayerClient; +import org.platformlayer.PlatformLayerClientException; +import org.platformlayer.jobs.model.JobExecutionData; +import org.platformlayer.jobs.model.JobExecutionList; +import org.platformlayer.jobs.model.JobState; +import org.platformlayer.xml.JsonHelper; + +import com.fathomdb.cli.CliException; +import com.fathomdb.cli.autocomplete.AutoCompletor; +import com.fathomdb.cli.autocomplete.SimpleAutoCompleter; +import com.fathomdb.cli.commands.Ansi; + +public class ListJobExecutions extends PlatformLayerCommandRunnerBase { + @Argument(index = 0) + public String jobId; + + public ListJobExecutions() { + super("list", "runs"); + } + + @Override + public Object runCommand() throws PlatformLayerClientException { + PlatformLayerClient client = getPlatformLayerClient(); + + JobExecutionList runs; + if (jobId == null) { + runs = client.listJobExecutions(); + } else { + runs = client.listJobExecutions(jobId); + } + + return runs; + } + + @Override + public AutoCompletor getAutoCompleter() { + return new SimpleAutoCompleter(); + } + + @Override + public void formatRaw(Object o, PrintWriter writer) { + JobExecutionList jobs = (JobExecutionList) o; + + switch (getFormat()) { + case JSON: + JsonHelper jsonHelper = JsonHelper.build(JobExecutionList.class); + boolean formatted = true; + try { + String json = jsonHelper.marshal(jobs, formatted); + writer.println(json); + return; + } catch (IOException e) { + throw new CliException("Error formatting for output", e); + } + } + + Ansi ansi = new Ansi(writer); + + for (JobExecutionData job : jobs) { + JobState state = job.state; + if (state != null) { + switch (job.state) { + case FAILED: + ansi.setColorRed(); + break; + + case SUCCESS: + ansi.setColorGreen(); + break; + + case RUNNING: + ansi.setColorBlue(); + break; + + default: + ansi.setColorBlue(); + break; + } + } else { + ansi.setColorBlue(); + } + + writer.println(job.getJobId() + "/" + job.executionId); + } + + ansi.reset(); + } + +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListJobs.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListJobs.java index 75f8598de..d88e06f2e 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListJobs.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListJobs.java @@ -1,7 +1,7 @@ package org.platformlayer.client.cli.commands; +import java.io.IOException; import java.io.PrintWriter; -import java.util.List; import org.kohsuke.args4j.Argument; import org.platformlayer.PlatformLayerClient; @@ -9,13 +9,13 @@ import org.platformlayer.client.cli.model.ItemPath; import org.platformlayer.core.model.PlatformLayerKey; import org.platformlayer.jobs.model.JobData; -import org.platformlayer.jobs.model.JobState; +import org.platformlayer.jobs.model.JobDataList; +import org.platformlayer.xml.JsonHelper; +import com.fathomdb.cli.CliException; import com.fathomdb.cli.autocomplete.AutoCompletor; import com.fathomdb.cli.autocomplete.SimpleAutoCompleter; import com.fathomdb.cli.commands.Ansi; -import com.google.common.base.Objects; -import com.google.common.collect.Lists; public class ListJobs extends PlatformLayerCommandRunnerBase { @Argument(index = 0) @@ -29,23 +29,28 @@ public ListJobs() { public Object runCommand() throws PlatformLayerClientException { PlatformLayerClient client = getPlatformLayerClient(); - List jobs = Lists.newArrayList(client.listJobs()); - - if (path != null) { + JobDataList jobs; + if (path == null) { + jobs = client.listJobs(); + } else { PlatformLayerKey resolved = path.resolve(getContext()); - - List matches = Lists.newArrayList(); - - for (JobData job : jobs) { - if (!Objects.equal(job.targetId, resolved)) { - continue; - } - - matches.add(job); - } - - jobs = matches; + jobs = client.listJobs(resolved); } + // if (path != null) { + // PlatformLayerKey resolved = path.resolve(getContext()); + // + // JobDataList matches = JobDataList.create(); + // + // for (JobData job : jobs.getJobs()) { + // if (!Objects.equal(job.getTargetItemKey(), resolved)) { + // continue; + // } + // + // matches.jobs.add(job); + // } + // + // jobs = matches; + // } return jobs; } @@ -57,32 +62,45 @@ public AutoCompletor getAutoCompleter() { @Override public void formatRaw(Object o, PrintWriter writer) { - Iterable jobs = (Iterable) o; + JobDataList jobs = (JobDataList) o; + + switch (getFormat()) { + case JSON: + JsonHelper jsonHelper = JsonHelper.build(JobDataList.class); + boolean formatted = true; + try { + String json = jsonHelper.marshal(jobs, formatted); + writer.println(json); + return; + } catch (IOException e) { + throw new CliException("Error formatting for output", e); + } + } Ansi ansi = new Ansi(writer); - for (JobData job : jobs) { - JobState state = job.state; - if (state != null) { - ansi.setColorBlue(); - switch (job.state) { - case FAILED: - ansi.setColorRed(); - break; - - case SUCCESS: - ansi.setColorGreen(); - break; - - case RUNNING: - ansi.setColorBlue(); - break; - - default: - ansi.setColorBlue(); - break; - } - } + for (JobData job : jobs.getJobs()) { + // JobState state = job.state; + // if (state != null) { + // ansi.setColorBlue(); + // switch (job.state) { + // case FAILED: + // ansi.setColorRed(); + // break; + // + // case SUCCESS: + // ansi.setColorGreen(); + // break; + // + // case RUNNING: + // ansi.setColorBlue(); + // break; + // + // default: + // ansi.setColorBlue(); + // break; + // } + // } writer.println(job.key); } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListMetrics.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListMetrics.java index 7344318b8..c40acd810 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListMetrics.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListMetrics.java @@ -18,10 +18,11 @@ public ListMetrics() { public Object runCommand() throws PlatformLayerClientException { PlatformLayerClient client = getPlatformLayerClient(); - PlatformLayerKey key = getContext().pathToItem(path); + PlatformLayerKey key = getContext().pathToItem(getProject(), path); MetricInfoCollection items = client.listMetrics(key); return items; } + } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListRoots.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListRoots.java index d62161bb5..8b0bbd49c 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListRoots.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListRoots.java @@ -4,8 +4,8 @@ import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientException; -import org.platformlayer.UntypedItem; import org.platformlayer.client.cli.output.UntypedItemFormatter; +import org.platformlayer.common.UntypedItem; import com.fathomdb.cli.commands.Ansi; diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListServices.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListServices.java index bbb8bccbd..d30ce76b1 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListServices.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListServices.java @@ -22,7 +22,7 @@ public Object runCommand() throws PlatformLayerClientException { public void formatRaw(Object o, PrintWriter writer) { Iterable services = (Iterable) o; for (ServiceInfo service : services) { - for (String publicType : service.publicTypes) { + for (String publicType : service.itemTypes) { writer.println(publicType); } } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListTags.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListTags.java index dd742dec6..87c75c044 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListTags.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ListTags.java @@ -3,8 +3,8 @@ import org.kohsuke.args4j.Argument; import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientException; -import org.platformlayer.UntypedItem; import org.platformlayer.client.cli.model.ItemPath; +import org.platformlayer.common.UntypedItem; import org.platformlayer.core.model.PlatformLayerKey; public class ListTags extends PlatformLayerCommandRunnerBase { @@ -20,8 +20,8 @@ public Object runCommand() throws PlatformLayerClientException { PlatformLayerClient client = getPlatformLayerClient(); PlatformLayerKey key = path.resolve(getContext()); - UntypedItem ret = client.getItemUntyped(key); + UntypedItem ret = client.getItemUntyped(key, getFormat()); - return ret.getTags().tags; + return ret.getTags(); } } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/OpenItem.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/OpenItem.java index e5e6f5f90..0d34dcf09 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/OpenItem.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/OpenItem.java @@ -4,11 +4,11 @@ import java.util.Set; import org.kohsuke.args4j.Argument; -import org.platformlayer.EndpointInfo; import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientException; -import org.platformlayer.UntypedItem; import org.platformlayer.client.cli.model.ItemPath; +import org.platformlayer.common.UntypedItem; +import org.platformlayer.core.model.EndpointInfo; import org.platformlayer.core.model.PlatformLayerKey; import com.fathomdb.cli.output.ClientAction; @@ -28,7 +28,7 @@ public Object runCommand() throws PlatformLayerClientException { PlatformLayerKey key = path.resolve(getContext()); - UntypedItem untypedItem = client.getItemUntyped(key); + UntypedItem untypedItem = client.getItemUntyped(key, getFormat()); List endpointList = EndpointInfo.getEndpoints(untypedItem.getTags()); Set endpoints = Sets.newHashSet(endpointList); diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PlatformLayerCommandRegistry.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PlatformLayerCommandRegistry.java index 21078962e..b92fdf061 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PlatformLayerCommandRegistry.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PlatformLayerCommandRegistry.java @@ -6,6 +6,6 @@ public class PlatformLayerCommandRegistry extends CommandRegistryBase { public PlatformLayerCommandRegistry() { addCommand(new AutoComplete()); - discoverCommands(getClass().getPackage()); + discoverCommands(); } } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PlatformLayerCommandRunnerBase.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PlatformLayerCommandRunnerBase.java index 90f47ec1d..3e0ef0151 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PlatformLayerCommandRunnerBase.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PlatformLayerCommandRunnerBase.java @@ -1,7 +1,22 @@ package org.platformlayer.client.cli.commands; +import java.io.PrintWriter; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; + +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMSource; + +import org.json.JSONException; +import org.json.JSONObject; +import org.platformlayer.Format; import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientException; +import org.platformlayer.PrimitiveComparators; +import org.platformlayer.UntypedItemJson; +import org.platformlayer.UntypedItemXml; import org.platformlayer.client.cli.PlatformLayerCliContext; import org.platformlayer.core.model.PlatformLayerKey; import org.platformlayer.core.model.ServiceInfo; @@ -9,11 +24,16 @@ import org.platformlayer.ids.ItemType; import org.platformlayer.ids.ProjectId; import org.platformlayer.ids.ServiceType; +import org.platformlayer.jobs.model.JobDataList; +import org.platformlayer.jobs.model.JobExecutionData; +import org.platformlayer.xml.DomUtils; +import com.fathomdb.cli.commands.Ansi; import com.fathomdb.cli.commands.CommandRunnerBase; import com.fathomdb.cli.commands.CommandSpecifier; public abstract class PlatformLayerCommandRunnerBase extends CommandRunnerBase { + public static final String NAMESPACE_URI_CORE = "http://platformlayer.org/core/v1.0"; protected PlatformLayerCommandRunnerBase(String verb, String noun) { super(verb, noun); @@ -32,11 +52,24 @@ protected PlatformLayerCliContext getContext() { return (PlatformLayerCliContext) super.getContext(); } + @Override + public Object convertToOutputFormat(Object results) { + if (results instanceof JobDataList) { + return ((JobDataList) results).getJobs(); + } + + return results; + } + + protected ProjectId getProject() { + return getContext().getProject(); + } + protected static String getServiceTypeFromItemType(PlatformLayerClient client, String itemType) throws PlatformLayerClientException { Iterable serviceInfo = client.listServices(true); for (ServiceInfo service : serviceInfo) { - for (String type : service.publicTypes) { + for (String type : service.itemTypes) { if (type.equals(itemType)) { return service.serviceType; } @@ -65,4 +98,63 @@ public static PlatformLayerKey pathToKey(PlatformLayerClient client, String path ProjectId project = client.getProject(); return new PlatformLayerKey(host, project, new ServiceType(serviceType), new ItemType(itemType), null); } + + protected Format getFormat() { + switch (getOutputFormat()) { + case Json: + return Format.JSON; + + default: + return Format.XML; + } + } + + @Override + public void formatRaw(Object o, PrintWriter writer) { + + String data; + if (o instanceof UntypedItemXml) { + UntypedItemXml item = (UntypedItemXml) o; + + Source src = new DOMSource(item.getRoot()); + String xml = DomUtils.toXml(src, 4); + data = xml; + } else if (o instanceof UntypedItemJson) { + UntypedItemJson item = (UntypedItemJson) o; + + JSONObject root = item.getRoot(); + try { + data = root.toString(2); + } catch (JSONException e) { + throw new IllegalStateException("Error formatting JSON", e); + } + } else { + super.formatRaw(o, writer); + return; + } + + Ansi ansi = new Ansi(writer); + + ansi.print(data); + ansi.println(); + + ansi.reset(); + } + + protected void sort(List runs) { + if (runs == null) { + return; + } + + Collections.sort(runs, new Comparator() { + @Override + public int compare(JobExecutionData o1, JobExecutionData o2) { + Date v1 = o1.startedAt; + Date v2 = o2.startedAt; + + return PrimitiveComparators.compare(v1, v2); + } + }); + } + } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PutChild.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PutChild.java deleted file mode 100644 index 4a79fa78f..000000000 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PutChild.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.platformlayer.client.cli.commands; - -import java.io.PrintWriter; - -import org.codehaus.jettison.json.JSONArray; -import org.codehaus.jettison.json.JSONException; -import org.codehaus.jettison.json.JSONObject; -import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.Option; -import org.platformlayer.Format; -import org.platformlayer.PlatformLayerClient; -import org.platformlayer.PlatformLayerClientException; -import org.platformlayer.UntypedItem; -import org.platformlayer.client.cli.model.ItemPath; -import org.platformlayer.core.model.PlatformLayerKey; -import org.platformlayer.core.model.Tag; - -public class PutChild extends PlatformLayerCommandRunnerBase { - @Argument(index = 0) - public ItemPath parent; - - @Argument(index = 1) - public ItemPath path; - - @Option(name = "-j", aliases = "--json", usage = "json") - @Argument(index = 2) - public String json; - - public PutChild() { - super("put", "child"); - } - - @Override - public Object runCommand() throws PlatformLayerClientException, JSONException { - PlatformLayerClient client = getPlatformLayerClient(); - - PlatformLayerKey parentKey; - - { - // We need to resolve to a full key - parentKey = parent.resolve(getContext()); - UntypedItem parentItem = client.getItemUntyped(parentKey); - if (parentItem == null) { - throw new IllegalArgumentException("Parent item not found: " + parent); - } - parentKey = parentItem.getPlatformLayerKey(); - } - PlatformLayerKey myKey = path.resolve(getContext()); - - // TODO: Should this be a common function? - JSONObject create = new JSONObject(json); - JSONArray jsonTags = null; - if (create.has("core.tags")) { - jsonTags = create.getJSONArray("core.tags"); - } else { - jsonTags = new JSONArray(); - create.put("core.tags", jsonTags); - } - - Tag parentTag = Tag.buildParentTag(parentKey); - - JSONObject jsonTag = new JSONObject(); - jsonTag.put("core.key", parentTag.getKey()); - jsonTag.put("core.value", parentTag.getValue()); - JSONObject jsonTagWrapper = new JSONObject(); - jsonTagWrapper.put("core.tags", jsonTag); - jsonTags.put(jsonTagWrapper); - - JSONObject wrapped = new JSONObject(); - wrapped.put(myKey.getItemType().getKey(), create); - - String data = wrapped.toString(); - - UntypedItem retval = client.putItem(myKey, data, Format.JSON); - - return retval; - } - - @Override - public void formatRaw(Object o, PrintWriter writer) { - UntypedItem item = (UntypedItem) o; - writer.println(item.getPlatformLayerKey()); - } - -} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PutItem.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PutItem.java index a9fb26f48..175720c07 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PutItem.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PutItem.java @@ -1,18 +1,36 @@ package org.platformlayer.client.cli.commands; +import java.io.IOException; +import java.io.InputStream; import java.io.PrintWriter; +import java.util.List; -import org.codehaus.jettison.json.JSONException; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Option; import org.platformlayer.Format; import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientException; -import org.platformlayer.UntypedItem; import org.platformlayer.client.cli.model.ItemPath; +import org.platformlayer.common.UntypedItem; import org.platformlayer.core.model.PlatformLayerKey; +import org.platformlayer.core.model.Tag; + +import com.fathomdb.cli.CliException; +import com.fathomdb.io.NoCloseInputStream; +import com.google.common.base.Charsets; +import com.google.common.collect.Lists; +import com.google.common.io.ByteStreams; public class PutItem extends PlatformLayerCommandRunnerBase { + @Option(name = "-p", aliases = "--parent", usage = "parent") + public ItemPath parent; + + @Option(name = "-tag", aliases = "--tag", usage = "tag") + public List tags = Lists.newArrayList(); + @Argument(index = 0) public ItemPath path; @@ -28,10 +46,81 @@ public PutItem() { public Object runCommand() throws PlatformLayerClientException, JSONException { PlatformLayerClient client = getPlatformLayerClient(); + if (json == null) { + InputStream stream = new NoCloseInputStream(System.in); + byte[] data; + try { + data = ByteStreams.toByteArray(stream); + + json = new String(data, Charsets.UTF_8); + } catch (IOException e) { + throw new CliException("Error reading stdin", e); + } + } + + JSONObject jsonObject = new JSONObject(json); + + PlatformLayerKey parentKey = null; + if (parent != null || !tags.isEmpty()) { + + JSONObject tagsObject = null; + if (jsonObject.has("tags")) { + tagsObject = jsonObject.getJSONObject("tags"); + } else { + tagsObject = new JSONObject(); + jsonObject.put("tags", tagsObject); + } + + JSONArray tagsArray; + if (tagsObject.has("tags")) { + tagsArray = tagsObject.getJSONArray("tags"); + } else { + tagsArray = new JSONArray(); + tagsObject.put("tags", tagsArray); + } + + if (parent != null) { + parentKey = parent.resolve(getContext()); + Tag parentTag = Tag.buildParentTag(parentKey); + + JSONObject jsonTag = new JSONObject(); + jsonTag.put("key", parentTag.getKey()); + jsonTag.put("value", parentTag.getValue()); + + tagsArray.put(jsonTag); + } + + for (String tag : tags) { + int equalsIndex = tag.indexOf('='); + if (equalsIndex == -1) { + throw new CliException("Expected tagname=tagvalue"); + } + + String tagName = tag.substring(0, equalsIndex); + String tagValue = tag.substring(equalsIndex + 1); + + JSONObject jsonTag = new JSONObject(); + jsonTag.put("key", tagName); + jsonTag.put("value", tagValue); + + tagsArray.put(jsonTag); + } + } + PlatformLayerKey key = path.resolve(getContext()); - String wrapper = "{ \"" + key.getItemType().getKey() + "\": " + json + " }"; - UntypedItem retval = client.putItem(key, wrapper, Format.JSON); + boolean wrap = false; + String data; + if (wrap) { + JSONObject wrapped = new JSONObject(); + wrapped.put(key.getItemType().getKey(), jsonObject); + + data = wrapped.toString(); + } else { + data = jsonObject.toString(); + } + + UntypedItem retval = client.putItem(key, data, Format.JSON); return retval; } @@ -39,7 +128,7 @@ public Object runCommand() throws PlatformLayerClientException, JSONException { @Override public void formatRaw(Object o, PrintWriter writer) { UntypedItem item = (UntypedItem) o; - writer.println(item.getPlatformLayerKey()); + writer.println(item.getKey()); } } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PutLink.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PutLink.java new file mode 100644 index 000000000..151bf0030 --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/PutLink.java @@ -0,0 +1,68 @@ +package org.platformlayer.client.cli.commands; + +import java.io.PrintWriter; +import java.util.Collection; +import java.util.List; + +import org.kohsuke.args4j.Argument; +import org.platformlayer.Format; +import org.platformlayer.PlatformLayerClient; +import org.platformlayer.PlatformLayerClientException; +import org.platformlayer.UntypedItemXml; +import org.platformlayer.client.cli.model.ItemPath; +import org.platformlayer.core.model.Link; +import org.platformlayer.core.model.Links; +import org.platformlayer.core.model.PlatformLayerKey; + +public class PutLink extends PlatformLayerCommandRunnerBase { + @Argument(index = 0, required = true, metaVar = "path") + public ItemPath path; + + @Argument(index = 1, required = true, metaVar = "name") + public String name; + + @Argument(index = 2, required = true, metaVar = "target") + public ItemPath target; + + public PutLink() { + super("put", "link"); + } + + @Override + public Object runCommand() throws PlatformLayerClientException { + PlatformLayerClient client = getPlatformLayerClient(); + + PlatformLayerKey resolved = path.resolve(getContext()); + + UntypedItemXml item = (UntypedItemXml) client.getItemUntyped(resolved, Format.XML); + + Links links = item.getLinks(); + + Link link = new Link(); + link.name = name; + link.target = target.resolve(getContext()); + + Link existing = links.findLink(name); + List linkList = links.getLinks(); + if (existing != null) { + linkList.remove(existing); + } + linkList.add(link); + + item.setLinks(links); + + String xml = item.serialize(); + + UntypedItemXml updated = (UntypedItemXml) client.putItem(resolved, xml, Format.XML); + + return updated.getLinks().getLinks(); + } + + @Override + public void formatRaw(Object o, PrintWriter writer) { + Collection links = (Collection) o; + for (Link link : links) { + writer.println(link.getName() + "\t" + link.getTarget()); + } + } +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ScriptCommands.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ScriptCommands.java index 4100c040f..509dddf73 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ScriptCommands.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ScriptCommands.java @@ -133,7 +133,7 @@ public static Object toPython(Object in) { for (Object item : list) { pythonObjects.add(toPython(item)); } - return FormattedList.build(context.getFormatterRegistry(), pythonObjects, true); + return FormattedList.build(context, pythonObjects, true); } // if (in instanceof UntypedItemCollection) { diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/SetProperty.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/SetProperty.java new file mode 100644 index 000000000..19a1f861b --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/SetProperty.java @@ -0,0 +1,75 @@ +package org.platformlayer.client.cli.commands; + +import java.io.IOException; +import java.io.InputStream; + +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.Option; +import org.platformlayer.PlatformLayerClient; +import org.platformlayer.PlatformLayerClientException; +import org.platformlayer.UntypedItemXml; +import org.platformlayer.client.cli.model.ItemPath; +import org.w3c.dom.Element; + +import com.fathomdb.cli.CliException; +import com.fathomdb.io.NoCloseInputStream; +import com.fathomdb.utils.Base64; +import com.google.common.io.ByteStreams; + +public class SetProperty extends ItemMutatorCommand { + @Option(name = "-stdin", usage = "Read value from stdin") + public boolean stdin; + + @Option(name = "-format", usage = "Format of data in stdin") + public String format; + + @Argument(index = 0, required = true, metaVar = "path") + public ItemPath path; + + @Argument(index = 1, required = true, metaVar = "key") + public String key; + @Argument(index = 2, required = false, metaVar = "value") + public String value; + + public SetProperty() { + super("set", "property"); + } + + @Override + public Object runCommand() throws PlatformLayerClientException, IOException { + PlatformLayerClient client = getPlatformLayerClient(); + + if (stdin) { + if (value != null) { + throw new CliException("You cannot specify a value when using -stdin"); + } + + InputStream stream = new NoCloseInputStream(System.in); + byte[] data = ByteStreams.toByteArray(stream); + + if ("base64".equals(format)) { + value = Base64.encode(data); + } else { + value = new String(data); + } + } else { + if (value == null) { + throw new CliException("Value is required (if not using -stdin)"); + } + } + + return runCommand(path); + } + + @Override + protected void changeItem(UntypedItemXml item) { + Element element = getElement(item, key); + + if (element == null) { + throw new CliException("Cannot find element: " + key); + } + + element.setTextContent(value); + } + +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/SshAddressFinder.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/SshAddressFinder.java new file mode 100644 index 000000000..198300202 --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/SshAddressFinder.java @@ -0,0 +1,65 @@ +package org.platformlayer.client.cli.commands; + +import java.net.InetAddress; +import java.util.List; +import java.util.Set; + +import org.platformlayer.PlatformLayerClient; +import org.platformlayer.PlatformLayerClientException; +import org.platformlayer.UntypedItemXml; +import org.platformlayer.common.UntypedItem; +import org.platformlayer.core.model.Tag; +import org.platformlayer.core.model.Tags; +import org.platformlayer.xml.XmlHelper.ElementInfo; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +public class SshAddressFinder { + public final List found = Lists.newArrayList(); + + final PlatformLayerClient client; + + public SshAddressFinder(PlatformLayerClient client) { + super(); + this.client = client; + } + + public void visit(UntypedItem item) throws PlatformLayerClientException { + UntypedItemXml untypedItem = (UntypedItemXml) item; + + ElementInfo rootElementInfo = untypedItem.getRootElementInfo(); + + boolean consider = true; + + switch (untypedItem.getState()) { + case DELETED: + case DELETE_REQUESTED: + consider = false; + break; + } + + Set instanceTypes = Sets.newHashSet(); + instanceTypes.add("directInstance"); + instanceTypes.add("googleCloudInstance"); + + if (!instanceTypes.contains(rootElementInfo.elementName)) { + consider = false; + } + + if (consider) { + Tags itemTags = untypedItem.getTags(); + + for (InetAddress address : Tag.NETWORK_ADDRESS.find(itemTags)) { + found.add(address); + } + } + + boolean includeDeleted = false; + + for (UntypedItem child : client.listChildren(untypedItem.getKey(), includeDeleted).getItems()) { + visit(child); + } + + } +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/SshItem.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/SshItem.java index 3c13b28d3..aa05a4e7c 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/SshItem.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/SshItem.java @@ -1,20 +1,21 @@ package org.platformlayer.client.cli.commands; -import java.util.List; -import java.util.Set; +import java.io.File; +import java.net.Inet6Address; +import java.net.InetAddress; import org.kohsuke.args4j.Argument; -import org.platformlayer.EndpointInfo; +import org.platformlayer.Format; import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientException; -import org.platformlayer.UntypedItem; import org.platformlayer.client.cli.model.ItemPath; +import org.platformlayer.common.UntypedItem; import org.platformlayer.core.model.PlatformLayerKey; -import org.platformlayer.core.model.Tag; -import org.platformlayer.core.model.Tags; +import org.platformlayer.ids.ProjectId; +import com.fathomdb.cli.CliException; import com.fathomdb.cli.output.ClientAction; -import com.google.common.collect.Sets; +import com.fathomdb.io.IoUtils; public class SshItem extends PlatformLayerCommandRunnerBase { @Argument @@ -30,43 +31,52 @@ public Object runCommand() throws PlatformLayerClientException { PlatformLayerKey key = path.resolve(getContext()); - UntypedItem untypedItem = client.getItemUntyped(key); - Tags itemTags = untypedItem.getTags(); - List endpointList = EndpointInfo.getEndpoints(itemTags); + UntypedItem untypedItem = client.getItemUntyped(key, Format.XML); - Set endpoints = Sets.newHashSet(endpointList); + InetAddress sshAddress = findSshAddress(client, untypedItem); - EndpointInfo bestEndpoint = null; - for (EndpointInfo candidate : endpoints) { - if (bestEndpoint == null) { - bestEndpoint = candidate; - } else { - throw new IllegalArgumentException("Cannot choose between: " + bestEndpoint + " and " + candidate); + ClientAction action = null; + if (sshAddress != null) { + String user = "root"; + + ProjectId project = key.getProject(); + if (project == null) { + project = client.getProject(); } - } + if (project == null) { + throw new CliException("Cannot determine project"); + } + String projectKey = project.getKey(); + String serviceKey = "service-" + key.getServiceType().getKey(); - String host = null; + File sshKey = IoUtils.resolve("~/.credentials/ssh/" + projectKey + "/" + serviceKey); - if (bestEndpoint != null) { - host = bestEndpoint.publicIp; + // Hmmm... user? key? + action = new ClientAction(ClientAction.ClientActionType.SSH, user + "@" + sshAddress.getHostAddress(), + sshKey.getAbsolutePath()); } - if (host == null) { - String addressTag = itemTags.findUnique(Tag.NETWORK_ADDRESS); - if (addressTag != null) { - int colonIndex = addressTag.indexOf(':'); - if (colonIndex != -1) { - host = addressTag.substring(colonIndex); - } + return action; + } + + private InetAddress findSshAddress(PlatformLayerClient client, UntypedItem untypedItem) + throws PlatformLayerClientException { + SshAddressFinder finder = new SshAddressFinder(client); + finder.visit(untypedItem); + + // IPV6 addresses aren't behind NAT, and so we prefer them + for (InetAddress address : finder.found) { + if (address instanceof Inet6Address) { + return address; } } - ClientAction action = null; - if (host != null) { - // Hmmm... user? key? - // action = new ClientAction(ClientAction.ClientActionType.SSH, "root@" + bestEndpoint); + // Fallback to whatever we can find.. + for (InetAddress address : finder.found) { + return address; } - return action; + return null; + } } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/TailLog.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/TailLog.java new file mode 100644 index 000000000..6ee27a4f1 --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/TailLog.java @@ -0,0 +1,144 @@ +package org.platformlayer.client.cli.commands; + +import java.io.PrintWriter; +import java.util.List; + +import org.kohsuke.args4j.Argument; +import org.platformlayer.PlatformLayerClient; +import org.platformlayer.PlatformLayerClientException; +import org.platformlayer.jobs.model.JobExecutionData; +import org.platformlayer.jobs.model.JobExecutionList; +import org.platformlayer.jobs.model.JobLog; +import org.platformlayer.jobs.model.JobLogLine; +import org.platformlayer.jobs.model.JobState; + +import com.google.common.base.Strings; + +public class TailLog extends PlatformLayerCommandRunnerBase { + @Argument(index = 0) + String jobId; + + @Argument(index = 1) + String executionId; + + public TailLog() { + super("tail", "log"); + } + + @Override + public Object runCommand() throws PlatformLayerClientException, InterruptedException { + PlatformLayerClient client = getPlatformLayerClient(); + + // TODO: System.out isn't quite right + JobLogPrinter jobLogPrinter = new JobLogPrinter(new PrintWriter(System.out)); + + if (Strings.isNullOrEmpty(executionId)) { + JobExecutionList jobExecutions = client.listJobExecutions(jobId); + + JobExecutionData last = null; + + for (JobExecutionData execution : jobExecutions.getRuns()) { + if (execution.getState() == JobState.PRESTART) { + continue; + } + + if (last == null) { + last = execution; + continue; + } + + if (last.getStartedAt().before(execution.getStartedAt())) { + last = execution; + continue; + } + } + + if (last != null) { + executionId = last.getExecutionId(); + } + } + + // TODO: What if executionId == null? Also retries.. + JobLog previousJobLog = null; + int jobLogOffset = 0; + + while (true) { + // TODO: Only fetch tail + JobLog jobLog = client.getJobExecutionLog(jobId, executionId); + if (previousJobLog == null) { + jobLogPrinter.startJobLog(jobLog); + } + + List lines = jobLog.getLines(); + + if (jobLogOffset < lines.size()) { + for (JobLogLine line : lines.subList(jobLogOffset, lines.size())) { + jobLogPrinter.write(line); + } + } + + jobLogPrinter.flush(); + + jobLogOffset = lines.size(); + previousJobLog = jobLog; + + Thread.sleep(1000); + } + } + + @Override + public void formatRaw(Object o, PrintWriter writer) { + // Ansi ansi = new Ansi(writer); + // + // List jobLogs = (List) o; + // for (JobLog jobLog : jobLogs) { + // int depth = 0; + // String indent = ""; + // + // for (JobLogLine line : jobLog) { + // String type = line.getType(); + // + // if (!Strings.isNullOrEmpty(type)) { + // if (type.equals(JobLogLine.TYPE_ENTER_SCOPE)) { + // writer.println(indent + ">>> " + line.message); + // depth++; + // indent += " "; + // } else if (type.equals(JobLogLine.TYPE_EXIT_SCOPE)) { + // depth--; + // indent = indent.substring(0, depth * 2); + // // writer.println(indent + "<<< " + line.message); + // } else { + // writer.println(indent + "??? " + line.message); + // } + // continue; + // } + // + // if (line.level >= JobLogLineLevels.LEVEL_ERROR) { + // ansi.setColorRed(); + // } else if (line.level >= JobLogLineLevels.LEVEL_WARN) { + // ansi.setColorYellow(); + // } else if (line.level >= JobLogLineLevels.LEVEL_INFO) { + // ansi.setColorGreen(); + // } else { + // ansi.setColorBlue(); + // } + // + // writer.print(indent); + // writer.println(line.message); + // + // JobLogExceptionInfo exceptionInfo = line.exception; + // while (exceptionInfo != null) { + // for (String exceptionLine : exceptionInfo.info) { + // writer.print(indent); + // writer.println(exceptionLine); + // } + // + // exceptionInfo = exceptionInfo.inner; + // } + // } + // } + // + // ansi.reset(); + } + +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ValidateItem.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ValidateItem.java new file mode 100644 index 000000000..70d5d2241 --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/commands/ValidateItem.java @@ -0,0 +1,22 @@ +package org.platformlayer.client.cli.commands; + +import org.kohsuke.args4j.Argument; +import org.platformlayer.PlatformLayerClientException; +import org.platformlayer.client.cli.model.ItemPath; +import org.platformlayer.core.model.ValidateAction; + +public class ValidateItem extends ActionCommandBase { + @Argument(index = 0, usage = "path", required = true) + public ItemPath path; + + public ValidateItem() { + super("validate"); + } + + @Override + public Object runCommand() throws PlatformLayerClientException { + ValidateAction action = new ValidateAction(); + return runAction(path, action); + } + +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/model/CliAction.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/model/CliAction.java new file mode 100644 index 000000000..5fab73d15 --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/model/CliAction.java @@ -0,0 +1,13 @@ +package org.platformlayer.client.cli.model; + +import com.fathomdb.cli.StringWrapper; +import com.fathomdb.cli.autocomplete.AutoCompleteAction; +import com.fathomdb.cli.autocomplete.HasAutoCompletor; + +@HasAutoCompletor(AutoCompleteAction.class) +public class CliAction extends StringWrapper { + public CliAction(String key) { + super(key); + } + +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/model/ConfigureAction.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/model/ConfigureAction.java deleted file mode 100644 index 88c583d02..000000000 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/model/ConfigureAction.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.platformlayer.client.cli.model; - -import com.fathomdb.cli.StringWrapper; -import com.fathomdb.cli.autocomplete.AutoCompleteAction; -import com.fathomdb.cli.autocomplete.HasAutoCompletor; - -@HasAutoCompletor(AutoCompleteAction.class) -public class ConfigureAction extends StringWrapper { - public ConfigureAction(String key) { - super(key); - } - -} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/model/ItemPath.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/model/ItemPath.java index 227c3a6d9..eec9d3c5b 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/model/ItemPath.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/model/ItemPath.java @@ -15,7 +15,7 @@ public ItemPath(String key) { } public PlatformLayerKey resolve(PlatformLayerCliContext context) throws PlatformLayerClientException { - return context.pathToItem(this.getKey()); + return context.pathToItem(context.getProject(), this.getKey()); } } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/JobDataFormatter.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/JobDataFormatter.java index 82851a9a2..cdf0aa9c3 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/JobDataFormatter.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/JobDataFormatter.java @@ -4,7 +4,9 @@ import java.util.LinkedHashMap; import org.platformlayer.jobs.model.JobData; +import org.platformlayer.jobs.model.JobExecutionData; +import com.fathomdb.cli.CliContext; import com.fathomdb.cli.formatter.SimpleFormatter; import com.fathomdb.cli.output.OutputSink; import com.google.common.collect.Maps; @@ -16,13 +18,18 @@ public JobDataFormatter() { } @Override - public void visit(JobData o, OutputSink sink) throws IOException { + public void visit(CliContext context, JobData o, OutputSink sink) throws IOException { LinkedHashMap values = Maps.newLinkedHashMap(); - values.put("key", o.key); + values.put("id", o.key.getItemIdString()); values.put("target", o.targetId); - values.put("action", o.action); - values.put("state", o.state); + values.put("action", o.action.getType()); + // values.put("state", o.state); + + JobExecutionData lastRun = o.getLastRun(); + values.put("lastrun:id", lastRun != null ? lastRun.getExecutionId() : null); + values.put("lastrun:state", lastRun != null ? lastRun.getState() : null); + values.put("lastrun:end", lastRun != null ? lastRun.getEndedAt() : null); sink.outputRow(values); } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/JobExecutionDataFormatter.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/JobExecutionDataFormatter.java new file mode 100644 index 000000000..4d89be26c --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/JobExecutionDataFormatter.java @@ -0,0 +1,42 @@ +package org.platformlayer.client.cli.output; + +import java.io.IOException; +import java.util.LinkedHashMap; + +import org.platformlayer.core.model.Action; +import org.platformlayer.jobs.model.JobData; +import org.platformlayer.jobs.model.JobExecutionData; + +import com.fathomdb.cli.CliContext; +import com.fathomdb.cli.formatter.SimpleFormatter; +import com.fathomdb.cli.output.OutputSink; +import com.google.common.collect.Maps; + +public class JobExecutionDataFormatter extends SimpleFormatter { + + public JobExecutionDataFormatter() { + super(JobExecutionData.class); + } + + @Override + public void visit(CliContext context, JobExecutionData o, OutputSink sink) throws IOException { + LinkedHashMap values = Maps.newLinkedHashMap(); + + values.put("jobId", o.getJobId()); + values.put("executionId", o.getExecutionId()); + JobData job = o.getJob(); + values.put("target", job != null ? job.getTargetItemKey() : null); + + Action action = null; + if (job != null) { + action = job.getAction(); + } + values.put("action", action != null ? action.getType() : null); + + values.put("startedAt", o.getStartedAt()); + values.put("endedAt", o.getEndedAt()); + values.put("state", o.getState()); + + sink.outputRow(values); + } +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/JobLogFormatter.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/JobLogFormatter.java new file mode 100644 index 000000000..926a3c5be --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/JobLogFormatter.java @@ -0,0 +1,42 @@ +package org.platformlayer.client.cli.output; + +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.List; + +import org.platformlayer.jobs.model.JobExecutionData; +import org.platformlayer.jobs.model.JobLog; +import org.platformlayer.jobs.model.JobLogLine; + +import com.fathomdb.cli.CliContext; +import com.fathomdb.cli.formatter.SimpleFormatter; +import com.fathomdb.cli.output.OutputSink; +import com.google.common.collect.Maps; + +public class JobLogFormatter extends SimpleFormatter { + + public JobLogFormatter() { + super(JobLog.class); + } + + @Override + public void visit(CliContext context, JobLog o, OutputSink sink) throws IOException { + LinkedHashMap values = Maps.newLinkedHashMap(); + + JobExecutionData execution = o.getExecution(); + if (execution != null) { + values.put("jobId", execution.getJobKey().getItemIdString()); + values.put("executionId", execution.getExecutionId()); + + values.put("start", o.getExecution().getStartedAt()); + values.put("end", o.getExecution().getEndedAt()); + + values.put("state", execution.getState()); + } + + List lines = o.getLines(); + values.put("lines", lines.size()); + + sink.outputRow(values); + } +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/JobLogLineFormatter.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/JobLogLineFormatter.java index 691cb7016..4b70e2733 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/JobLogLineFormatter.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/JobLogLineFormatter.java @@ -5,6 +5,7 @@ import org.platformlayer.jobs.model.JobLogLine; +import com.fathomdb.cli.CliContext; import com.fathomdb.cli.formatter.SimpleFormatter; import com.fathomdb.cli.output.OutputSink; import com.google.common.collect.Maps; @@ -16,7 +17,7 @@ public JobLogLineFormatter() { } @Override - public void visit(JobLogLine o, OutputSink sink) throws IOException { + public void visit(CliContext context, JobLogLine o, OutputSink sink) throws IOException { LinkedHashMap values = Maps.newLinkedHashMap(); values.put("timestamp", o.timestamp); diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/LinkFormatter.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/LinkFormatter.java new file mode 100644 index 000000000..3b50a377d --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/LinkFormatter.java @@ -0,0 +1,28 @@ +package org.platformlayer.client.cli.output; + +import java.io.IOException; +import java.util.LinkedHashMap; + +import org.platformlayer.core.model.Link; + +import com.fathomdb.cli.CliContext; +import com.fathomdb.cli.formatter.SimpleFormatter; +import com.fathomdb.cli.output.OutputSink; +import com.google.common.collect.Maps; + +public class LinkFormatter extends SimpleFormatter { + + public LinkFormatter() { + super(Link.class); + } + + @Override + public void visit(CliContext context, Link o, OutputSink sink) throws IOException { + LinkedHashMap values = Maps.newLinkedHashMap(); + + values.put("name", o.getName()); + values.put("target", o.getTarget().toString()); + + sink.outputRow(values); + } +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/MetricDataStreamFormatter.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/MetricDataStreamFormatter.java new file mode 100644 index 000000000..feabd6eae --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/MetricDataStreamFormatter.java @@ -0,0 +1,29 @@ +package org.platformlayer.client.cli.output; + +import java.io.IOException; +import java.util.LinkedHashMap; + +import org.platformlayer.metrics.model.MetricDataStream; + +import com.fathomdb.cli.CliContext; +import com.fathomdb.cli.formatter.SimpleFormatter; +import com.fathomdb.cli.output.OutputSink; +import com.google.common.collect.Maps; + +public class MetricDataStreamFormatter extends SimpleFormatter { + + public MetricDataStreamFormatter() { + super(MetricDataStream.class); + } + + @Override + public void visit(CliContext context, MetricDataStream o, OutputSink sink) throws IOException { + LinkedHashMap values = Maps.newLinkedHashMap(); + + // values.put("time", o.getTime()); + values.put("value", MetricToJsonVisitor.toString(o)); + + sink.outputRow(values); + } + +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/MetricInfoFormatter.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/MetricInfoFormatter.java index f7b6ae4c0..1522d99c4 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/MetricInfoFormatter.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/MetricInfoFormatter.java @@ -5,6 +5,7 @@ import org.platformlayer.metrics.model.MetricInfo; +import com.fathomdb.cli.CliContext; import com.fathomdb.cli.formatter.SimpleFormatter; import com.fathomdb.cli.output.OutputSink; import com.google.common.collect.Maps; @@ -16,7 +17,7 @@ public MetricInfoFormatter() { } @Override - public void visit(MetricInfo o, OutputSink sink) throws IOException { + public void visit(CliContext context, MetricInfo o, OutputSink sink) throws IOException { LinkedHashMap values = Maps.newLinkedHashMap(); values.put("key", o.getKey()); diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/MetricToJsonVisitor.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/MetricToJsonVisitor.java new file mode 100644 index 000000000..212bb7807 --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/MetricToJsonVisitor.java @@ -0,0 +1,113 @@ +package org.platformlayer.client.cli.output; + +import java.io.Closeable; +import java.io.IOException; +import java.io.OutputStream; +import java.io.StringWriter; +import java.io.Writer; + +import org.platformlayer.metrics.model.MetricDataStream; +import org.platformlayer.metrics.model.MetricDataVisitor; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerator; + +public class MetricToJsonVisitor implements MetricDataVisitor, Closeable { + + final JsonGenerator jsonGenerator; + + public MetricToJsonVisitor(OutputStream os) throws IOException { + JsonFactory jsonFactory = buildJsonFactory(); + JsonGenerator jsonGenerator = jsonFactory.createJsonGenerator(os); + + this.jsonGenerator = jsonGenerator; + } + + public MetricToJsonVisitor(Writer writer) throws IOException { + JsonFactory jsonFactory = buildJsonFactory(); + JsonGenerator jsonGenerator = jsonFactory.createJsonGenerator(writer); + jsonGenerator.useDefaultPrettyPrinter(); + this.jsonGenerator = jsonGenerator; + } + + private JsonFactory buildJsonFactory() { + return new JsonFactory(); + } + + public static String toString(MetricDataStream s) throws IOException { + // TODO: This is not very efficient; we deserialize a JSON stream and reserialize it + StringWriter writer = new StringWriter(); + + MetricToJsonVisitor visitor = new MetricToJsonVisitor(writer); + s.accept(visitor); + visitor.close(); + + return writer.toString(); + } + + @Override + public void startObject() throws IOException { + jsonGenerator.writeStartObject(); + } + + @Override + public void endObject() throws IOException { + jsonGenerator.writeEndObject(); + } + + @Override + public void gotValueString(String s) throws IOException { + jsonGenerator.writeString(s); + } + + @Override + public void gotKey(String key) throws IOException { + jsonGenerator.writeFieldName(key); + } + + @Override + public void startArray() throws IOException { + jsonGenerator.writeStartArray(); + } + + @Override + public void endArray() throws IOException { + jsonGenerator.writeEndArray(); + } + + @Override + public void gotValueBoolean(boolean v) throws IOException { + jsonGenerator.writeBoolean(v); + } + + @Override + public void gotValueNull() throws IOException { + jsonGenerator.writeNull(); + } + + @Override + public void gotValueInt(int v) throws IOException { + jsonGenerator.writeNumber(v); + } + + @Override + public void gotValueFloat(float v) throws IOException { + jsonGenerator.writeNumber(v); + } + + @Override + public void gotValueDouble(double v) throws IOException { + jsonGenerator.writeNumber(v); + } + + @Override + public void gotValueLong(long v) throws IOException { + jsonGenerator.writeNumber(v); + } + + @Override + public void close() throws IOException { + jsonGenerator.close(); + } + +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/MetricValueFormatter.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/MetricValueFormatter.java index a4eef224b..7059e819f 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/MetricValueFormatter.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/MetricValueFormatter.java @@ -5,6 +5,7 @@ import org.platformlayer.metrics.model.MetricValue; +import com.fathomdb.cli.CliContext; import com.fathomdb.cli.formatter.SimpleFormatter; import com.fathomdb.cli.output.OutputSink; import com.google.common.collect.Maps; @@ -16,7 +17,7 @@ public MetricValueFormatter() { } @Override - public void visit(MetricValue o, OutputSink sink) throws IOException { + public void visit(CliContext context, MetricValue o, OutputSink sink) throws IOException { LinkedHashMap values = Maps.newLinkedHashMap(); values.put("time", o.getTime()); diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/PlatformLayerFormatterRegistry.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/PlatformLayerFormatterRegistry.java index e86b6157c..18223ac39 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/PlatformLayerFormatterRegistry.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/PlatformLayerFormatterRegistry.java @@ -9,11 +9,15 @@ public PlatformLayerFormatterRegistry() { addFormatter(new TagFormatter()); addFormatter(new JobDataFormatter()); + addFormatter(new JobLogFormatter()); + addFormatter(new JobExecutionDataFormatter()); addFormatter(new JobLogLineFormatter()); addFormatter(new ServiceInfoFormatter()); addFormatter(new UntypedItemFormatter()); + addFormatter(new MetricDataStreamFormatter()); addFormatter(new MetricInfoFormatter()); addFormatter(new MetricValueFormatter()); + addFormatter(new PlatformLayerKeyFormatter()); } } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/PlatformLayerKeyFormatter.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/PlatformLayerKeyFormatter.java new file mode 100644 index 000000000..f5bc19130 --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/PlatformLayerKeyFormatter.java @@ -0,0 +1,35 @@ +package org.platformlayer.client.cli.output; + +import java.io.IOException; +import java.util.LinkedHashMap; + +import org.platformlayer.client.cli.PlatformLayerCliContext; +import org.platformlayer.core.model.PlatformLayerKey; + +import com.fathomdb.cli.CliContext; +import com.fathomdb.cli.formatter.SimpleFormatter; +import com.fathomdb.cli.output.OutputSink; +import com.google.common.collect.Maps; + +public class PlatformLayerKeyFormatter extends SimpleFormatter { + + public PlatformLayerKeyFormatter() { + super(PlatformLayerKey.class); + } + + @Override + public void visit(CliContext context, PlatformLayerKey o, OutputSink sink) throws IOException { + + String s = null; + + if (o != null) { + s = Utils.formatUrl((PlatformLayerCliContext) context, o); + } + + LinkedHashMap values = Maps.newLinkedHashMap(); + + values.put("key", s); + + sink.outputRow(values); + } +} diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/ServiceInfoFormatter.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/ServiceInfoFormatter.java index 9690f4b16..0e9913b56 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/ServiceInfoFormatter.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/ServiceInfoFormatter.java @@ -5,6 +5,7 @@ import org.platformlayer.core.model.ServiceInfo; +import com.fathomdb.cli.CliContext; import com.fathomdb.cli.formatter.SimpleFormatter; import com.fathomdb.cli.output.OutputSink; import com.google.common.collect.Maps; @@ -16,14 +17,13 @@ public ServiceInfoFormatter() { } @Override - public void visit(ServiceInfo o, OutputSink sink) throws IOException { + public void visit(CliContext context, ServiceInfo o, OutputSink sink) throws IOException { LinkedHashMap values = Maps.newLinkedHashMap(); values.put("serviceType", o.getServiceType()); values.put("namespace", o.getNamespace()); values.put("description", o.getDescription()); - values.put("publicTypes", o.getPublicTypes()); - values.put("adminTypes", o.getAdminTypes()); + values.put("allTypes", o.getItemTypes()); sink.outputRow(values); } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/TagFormatter.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/TagFormatter.java index 982fd6e4f..9df873ce2 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/TagFormatter.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/TagFormatter.java @@ -5,6 +5,7 @@ import org.platformlayer.core.model.Tag; +import com.fathomdb.cli.CliContext; import com.fathomdb.cli.formatter.SimpleFormatter; import com.fathomdb.cli.output.OutputSink; import com.google.common.collect.Maps; @@ -16,7 +17,7 @@ public TagFormatter() { } @Override - public void visit(Tag o, OutputSink sink) throws IOException { + public void visit(CliContext context, Tag o, OutputSink sink) throws IOException { LinkedHashMap values = Maps.newLinkedHashMap(); values.put("key", o.getKey()); diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/UntypedItemFormatter.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/UntypedItemFormatter.java index f914c5f61..5d64d6538 100644 --- a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/UntypedItemFormatter.java +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/UntypedItemFormatter.java @@ -2,32 +2,39 @@ import java.io.IOException; import java.util.LinkedHashMap; +import java.util.List; -import javax.xml.transform.TransformerException; - -import org.platformlayer.UntypedItem; +import org.platformlayer.UntypedItemXml; +import org.platformlayer.client.cli.PlatformLayerCliContext; +import org.platformlayer.common.UntypedItem; import org.platformlayer.core.model.PlatformLayerKey; -import org.platformlayer.xml.XmlHelper; +import org.platformlayer.core.model.Tag; +import org.platformlayer.core.model.Tags; +import org.platformlayer.xml.DomUtils; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import com.fathomdb.cli.CliContext; import com.fathomdb.cli.commands.Ansi; import com.fathomdb.cli.formatter.SimpleFormatter; import com.fathomdb.cli.output.OutputSink; import com.google.common.collect.Maps; -@SuppressWarnings("rawtypes") public class UntypedItemFormatter extends SimpleFormatter { public UntypedItemFormatter() { super(UntypedItem.class); } @Override - public void visit(UntypedItem o, OutputSink sink) throws IOException { + public void visit(CliContext contextGeneric, UntypedItem o, OutputSink sink) throws IOException { + PlatformLayerCliContext context = (PlatformLayerCliContext) contextGeneric; + LinkedHashMap values = Maps.newLinkedHashMap(); - Element dataElement = o.getDataElement(); + UntypedItemXml item = (UntypedItemXml) o; + + Element dataElement = item.getDataElement(); // String xml = o.getModelData(); // @@ -40,18 +47,68 @@ public void visit(UntypedItem o, OutputSink sink) throws IOException { // throw new IllegalArgumentException("Error parsing XML", e); // } - values.put("key", o.getPlatformLayerKey().getUrl()); - values.put("state", o.getState()); + values.put("key", Utils.formatUrl(context, item.getKey())); + values.put("state", item.getState()); + + Tags tags = item.getTags(); + values.put("tags", tagsToString(context, tags)); NodeList childNodes = dataElement.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { - Node item = childNodes.item(i); - values.put(item.getNodeName(), formatCell(item)); + Node node = childNodes.item(i); + String nodeName = node.getNodeName(); + String localName = node.getLocalName(); + String namespace = node.getNamespaceURI(); + + if (namespace.equals("http://platformlayer.org/core/v1.0")) { + if (localName.equals("tags")) { + continue; + } + + if (localName.equals("key")) { + continue; + } + + if (localName.equals("version")) { + continue; + } + + if (localName.equals("state")) { + continue; + } + } + + String text = formatCell(node); + text = Utils.reformatText(context, text); + values.put(nodeName, text); } sink.outputRow(values); } + private String tagsToString(PlatformLayerCliContext context, Tags tags) { + if (tags == null) { + return ""; + } + + List tagList = tags.getTags(); + if (tagList == null) { + return ""; + } + + StringBuilder sb = new StringBuilder(); + for (Tag tag : tagList) { + if (sb.length() != 0) { + sb.append(", "); + } + String value = tag.getValue(); + value = Utils.reformatText(context, value); + sb.append(tag.getKey() + "=" + value); + } + + return sb.toString(); + } + private String formatCell(Node node) { switch (node.getNodeType()) { case Node.ATTRIBUTE_NODE: @@ -79,14 +136,12 @@ private String formatElementAsCell(Element node) { return formatCell(childNodes.item(0)); } - try { - return XmlHelper.toXml(node); - } catch (TransformerException e) { - throw new IllegalArgumentException("Error formatting XML to text", e); - } + return DomUtils.toXml(node); } - public static void formatItem(UntypedItem item, Ansi ansi, boolean fullPath) { + public static void formatItem(UntypedItem o, Ansi ansi, boolean fullPath) { + UntypedItemXml item = (UntypedItemXml) o; + Ansi.Action action = null; switch (item.getState()) { @@ -114,12 +169,12 @@ public static void formatItem(UntypedItem item, Ansi ansi, boolean fullPath) { } try { - PlatformLayerKey plk = item.getPlatformLayerKey(); + PlatformLayerKey plk = item.getKey(); if (fullPath) { - ansi.println(plk.getUrl()); + ansi.print(plk.getUrl()); } else { - ansi.println(plk.getItemId().getKey()); + ansi.print(plk.getItemId().getKey()); } } finally { if (undo != null) { @@ -127,6 +182,8 @@ public static void formatItem(UntypedItem item, Ansi ansi, boolean fullPath) { } } + ansi.println(); + } } diff --git a/bindings/cli/src/main/java/org/platformlayer/client/cli/output/Utils.java b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/Utils.java new file mode 100644 index 000000000..2573b9a48 --- /dev/null +++ b/bindings/cli/src/main/java/org/platformlayer/client/cli/output/Utils.java @@ -0,0 +1,35 @@ +package org.platformlayer.client.cli.output; + +import org.platformlayer.client.cli.PlatformLayerCliContext; +import org.platformlayer.core.model.PlatformLayerKey; +import org.platformlayer.ids.ProjectId; + +import com.google.common.base.Objects; + +public class Utils { + public static String formatUrl(PlatformLayerCliContext context, PlatformLayerKey key) { + String text = key.getUrl(); + + if (key.getHost() == null) { + ProjectId project = context.getProject(); + if (Objects.equal(project, context.getProject())) { + text = "pl:" + key.getItemTypeString() + "/" + key.getItemIdString(); + } + } + + return text; + } + + public static String reformatText(PlatformLayerCliContext context, String text) { + if (text.startsWith("platform://")) { + // This looks like a PlatformLayerKey + try { + PlatformLayerKey key = PlatformLayerKey.parse(text); + text = formatUrl(context, key); + } catch (Exception e) { + // Ignore + } + } + return text; + } +} diff --git a/bindings/cli/src/main/resources/log4j.properties b/bindings/cli/src/main/resources/log4j.properties deleted file mode 100644 index e0c1c6373..000000000 --- a/bindings/cli/src/main/resources/log4j.properties +++ /dev/null @@ -1,5 +0,0 @@ -log4j.rootLogger=DEBUG, CONSOLE - -log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender -log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout -log4j.appender.CONSOLE.layout.ConversionPattern=%d [%t] %-5p %c - %m%n diff --git a/bindings/cli/src/main/resources/logback.xml b/bindings/cli/src/main/resources/logback.xml new file mode 100644 index 000000000..070671efc --- /dev/null +++ b/bindings/cli/src/main/resources/logback.xml @@ -0,0 +1,14 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + diff --git a/bindings/platformlayer-api/pom.xml b/bindings/platformlayer-api/pom.xml index 8410b95b9..bdd757410 100644 --- a/bindings/platformlayer-api/pom.xml +++ b/bindings/platformlayer-api/pom.xml @@ -15,6 +15,22 @@ org.platformlayer platformlayer-shared-utils + + + jaxb-impl + com.sun.xml.bind + + + + + + org.json + json + + + + com.fathomdb + fathomdb-http @@ -22,21 +38,38 @@ core-model - org.platformlayer - keystone-client + platformlayer-auth-client + + + + org.slf4j + slf4j-api + + + com.google.protobuf + protobuf-java + provided + + + + javax.inject + javax.inject + + + - + org.jvnet.jaxb2.maven2 - + maven-jaxb2-plugin + 0.8.3 src/main/schemas/resolver.cat src/main/schemas @@ -47,19 +80,9 @@ -extension - + - - - - generate - - - diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/AndFilter.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/AndFilter.java new file mode 100644 index 000000000..6c680b6ea --- /dev/null +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/AndFilter.java @@ -0,0 +1,47 @@ +package org.platformlayer; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +import org.platformlayer.core.model.ItemBase; +import org.platformlayer.core.model.Tag; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +public class AndFilter extends Filter { + + private final Filter[] filters; + + public AndFilter(Filter[] filters) { + this.filters = filters; + } + + @Override + public boolean matchesItem(T item) { + for (Filter filter : filters) { + if (!filter.matchesItem(item)) { + return false; + } + } + return true; + } + + @Override + public String toString() { + return "AndFilter [filters=" + Arrays.toString(filters) + "]"; + } + + @Override + public List getRequiredTags() { + Set tags = Sets.newHashSet(); + + for (Filter filter : filters) { + tags.addAll(filter.getRequiredTags()); + } + + return Lists.newArrayList(tags); + } + +} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/DirectPlatformLayerClient.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/DirectPlatformLayerClient.java deleted file mode 100644 index e8c97a40e..000000000 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/DirectPlatformLayerClient.java +++ /dev/null @@ -1,406 +0,0 @@ -package org.platformlayer; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.List; -import java.util.Properties; - -import org.openstack.keystone.auth.client.KeystoneAuthenticator; -import org.openstack.utils.PropertyUtils; -import org.platformlayer.auth.Authenticator; -import org.platformlayer.core.model.Action; -import org.platformlayer.core.model.PlatformLayerKey; -import org.platformlayer.core.model.ServiceInfo; -import org.platformlayer.core.model.ServiceInfoCollection; -import org.platformlayer.core.model.Tag; -import org.platformlayer.core.model.TagChanges; -import org.platformlayer.core.model.Tags; -import org.platformlayer.federation.model.PlatformLayerConnectionConfiguration; -import org.platformlayer.ids.ItemType; -import org.platformlayer.ids.ManagedItemId; -import org.platformlayer.ids.ProjectId; -import org.platformlayer.ids.ServiceType; -import org.platformlayer.jobs.model.JobData; -import org.platformlayer.jobs.model.JobDataList; -import org.platformlayer.jobs.model.JobLog; -import org.platformlayer.metrics.model.MetricInfoCollection; -import org.platformlayer.metrics.model.MetricValues; -import org.platformlayer.xml.JaxbHelper; -import org.platformlayer.xml.UnmarshalException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DirectPlatformLayerClient extends PlatformLayerClientBase { - public static final String SERVICE_PLATFORMLAYER = "platformlayer"; - - static final Logger log = LoggerFactory.getLogger(DirectPlatformLayerClient.class); - - List services; - - private final ProjectId projectId; - - private final PlatformLayerHttpClient httpClient; - - private DirectPlatformLayerClient(PlatformLayerHttpClient httpClient, ProjectId projectId) { - this.httpClient = httpClient; - this.projectId = projectId; - } - - public static DirectPlatformLayerClient buildUsingSavedConfiguration(String key) throws IOException { - File credentialsFile = new File(System.getProperty("user.home") + File.separator + ".credentials" - + File.separator + key); - if (!credentialsFile.exists()) { - throw new FileNotFoundException("Credentials file not found: " + credentialsFile); - } - - Properties properties; - try { - properties = PropertyUtils.loadProperties(credentialsFile); - } catch (IOException e) { - throw new IOException("Error reading credentials file: " + credentialsFile, e); - } - - return buildUsingProperties(properties); - } - - public static DirectPlatformLayerClient buildUsingConfiguration(PlatformLayerConnectionConfiguration config) { - String tenant = config.tenant; - String server = config.server; - String username = config.username; - String secret = config.secret; - - Authenticator authenticator = new KeystoneAuthenticator(tenant, username, secret, server); - ProjectId projectId = new ProjectId(tenant); - return build(authenticator, projectId); - } - - public static DirectPlatformLayerClient buildUsingProperties(Properties properties) { - PlatformLayerConnectionConfiguration config = new PlatformLayerConnectionConfiguration(); - config.tenant = properties.getProperty("platformlayer.tenant"); - config.server = properties.getProperty("platformlayer.auth"); - config.username = properties.getProperty("platformlayer.username"); - config.secret = properties.getProperty("platformlayer.password"); - - return buildUsingConfiguration(config); - } - - public static DirectPlatformLayerClient build(Authenticator authenticator, ProjectId projectId) { - return new DirectPlatformLayerClient(new PlatformLayerHttpClient(authenticator), projectId); - } - - @Override - public List listServices(boolean allowCache) throws PlatformLayerClientException { - if (!allowCache || services == null) { - ServiceInfoCollection ret = httpClient.doSimpleRequest("/", ServiceInfoCollection.class, Format.XML); - services = ret.services; - } - - return services; - } - - @Override - public void ensureLoggedIn() throws PlatformLayerAuthenticationException { - httpClient.getAuthenticationToken(); - } - - // public String createItem(ServiceType serviceType, ItemType itemType, String data, Format format) throws - // PlatformLayerClientException { - // String relativePath = buildRelativePath(serviceType, itemType, null); - // - // return httpClient.doRequest("POST", relativePath, String.class, data, format); - // } - - public UntypedItem putItem(ServiceType serviceType, ItemType itemType, ManagedItemId id, String data, - Format dataFormat) throws PlatformLayerClientException { - if (id == null) { - throw new IllegalArgumentException("id is required on a put"); - } - - String relativePath = buildRelativePath(serviceType, itemType, id); - - String xml = httpClient.doRequest("PUT", relativePath, String.class, Format.XML, data, dataFormat); - return UntypedItem.build(xml); - } - - @Override - public UntypedItem putItemByTag(PlatformLayerKey key, Tag uniqueTag, String data, Format dataFormat) - throws PlatformLayerClientException { - if (key.getItemId() == null) { - throw new IllegalArgumentException("id is required on a put"); - } - - String relativePath = buildRelativePath(key); - - if (uniqueTag != null) { - relativePath += "?unique=" + encodeArgument(uniqueTag.getKey()); - } - - String xml = httpClient.doRequest("PUT", relativePath, String.class, Format.XML, data, dataFormat); - UntypedItem item = UntypedItem.build(xml); - - // PlatformLayerKey platformLayerKey = item.getPlatformLayerKey(); - // platformLayerKey = platformLayerKey.withId(new ManagedItemId(item.getId())); - // item.setPlatformLayerKey(platformLayerKey); - - return item; - } - - private String encodeArgument(String s) { - try { - return URLEncoder.encode(s, "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new IllegalStateException("UTF-8 not supported", e); - } - } - - @Override - public UntypedItem putItem(PlatformLayerKey key, String data, Format dataFormat) - throws PlatformLayerClientException { - return putItem(key.getServiceType(), key.getItemType(), key.getItemId(), data, dataFormat); - } - - @Override - public String activateService(String serviceType, String data, Format dataFormat) - throws PlatformLayerClientException { - String relativePath = "/authorizations/" + serviceType + "/"; - - return httpClient.doRequest("POST", relativePath, String.class, Format.XML, data, dataFormat); - } - - @Override - public String getActivation(String serviceType, Format format) throws PlatformLayerClientException { - String relativePath = "/authorizations/" + serviceType + "/"; - - return httpClient.doRequest("GET", relativePath, String.class, format, null, null); - } - - @Override - public String getSshPublicKey(String serviceType) throws PlatformLayerClientException { - String relativePath = "/" + serviceType + "/sshkey"; - - return httpClient.doRequest("GET", relativePath, String.class, Format.TEXT, null, null); - } - - @Override - public String getSchema(String serviceType, Format format) throws PlatformLayerClientException { - String relativePath = "/" + serviceType + "/schema"; - - return httpClient.doRequest("GET", relativePath, String.class, format, null, null); - } - - // public T createItem(T item) throws PlatformLayerClientException { - // JaxbHelper jaxbHelper = toJaxbHelper(item); - // - // String xml = serialize(jaxbHelper, item); - // - // PlatformLayerKey key = toKey(jaxbHelper, item); - // - // String relativePath = buildRelativePath(key); - // - // String retval = httpClient.doRequest("POST", relativePath, String.class, xml, Format.XML); - // - // T created = deserializeItem((Class) item.getClass(), retval); - // - // setPlatformLayerKey(created, key); - // - // return created; - // } - - @Override - public Tags changeTags(PlatformLayerKey key, TagChanges tagChanges) throws PlatformLayerClientException { - return changeTags(key.getServiceType(), key.getItemType(), key.getItemId(), tagChanges); - } - - public Tags changeTags(ServiceType serviceType, ItemType itemType, ManagedItemId id, TagChanges tagChanges) - throws PlatformLayerClientException { - String url = buildRelativePath(serviceType, itemType, id) + "/tags"; - Tags retval = httpClient.doRequest("POST", url, Tags.class, Format.XML, tagChanges, Format.XML); - return retval; - } - - // public void deleteItem(T item) throws PlatformLayerClientException { - // JaxbHelper jaxbHelper = toJaxbHelper(item); - // - // PlatformLayerKey key = toKey(jaxbHelper, item); - // deleteItem(key); - // } - - @Override - public void deleteItem(PlatformLayerKey key) throws PlatformLayerClientException { - String relativePath = buildRelativePath(key); - - httpClient.doRequest("DELETE", relativePath, String.class, Format.XML, null, null); - } - - // public List listItems(Class clazz) throws PlatformLayerClientException { - // return listItems(clazz, (Filter) null); - // } - // - // public List listItems(Class clazz, Tag tag) throws PlatformLayerClientException { - // return listItems(clazz, Filter.byTag(tag)); - // } - - // public List listItems(Class clazz, Filter filter) throws PlatformLayerClientException { - // JaxbHelper jaxbHelper = toJaxbHelper(clazz, ManagedItemCollection.class); - // PlatformLayerKey key = toKey(jaxbHelper); - // - // String xml = doListItemsRequest(key); - // - // ManagedItemCollection items; - // try { - // items = jaxbHelper.deserialize(new StringReader(xml), ManagedItemCollection.class); - // } catch (UnmarshalException e) { - // throw new PlatformLayerClientException("Error parsing returned data", e); - // } - // - // if (filter != null) { - // // TODO: Do filtering server-side - // List filtered = Lists.newArrayList(); - // for (T item : items.items) { - // if (filter.matches(item)) { - // filtered.add(item); - // } - // } - // return filtered; - // } else { - // return items.items; - // } - // } - - // public T getItem(Class clazz, PlatformLayerKey key) throws PlatformLayerClientException { - // if (key.getHost() != null) - // throw new UnsupportedOperationException(); - // - // String relativePath = buildRelativePath(key); - // T item = httpClient.doRequest("GET", relativePath, clazz, Format.XML, null, Format.XML); - // - // setPlatformLayerKey(item, key); - // - // return item; - // } - - // private void setPlatformLayerKey(T item, PlatformLayerKey key) { - // if (item instanceof ItemBase) { - // ((ItemBase) item).setKey(key); - // } else { - // throw new IllegalStateException(); - // } - // } - - private String doListItemsRequest(PlatformLayerKey path) throws PlatformLayerClientException { - String relativePath = buildRelativePath(path); - String retval = httpClient.doRequest("GET", relativePath, String.class, Format.XML, null, null); - return retval; - } - - @Override - public UntypedItemCollection listItemsUntyped(PlatformLayerKey path) throws PlatformLayerClientException { - String xml = doListItemsRequest(path); - - return UntypedItemCollection.build(xml); - } - - private String doListRootsRequest() throws PlatformLayerClientException { - String relativePath = "roots"; - String retval = httpClient.doRequest("GET", relativePath, String.class, Format.XML, null, null); - return retval; - } - - @Override - public UntypedItemCollection listRoots() throws PlatformLayerClientException { - String xml = doListRootsRequest(); - - return UntypedItemCollection.build(xml); - } - - @Override - public UntypedItemCollection listChildren(PlatformLayerKey parent) throws PlatformLayerClientException { - String relativePath = buildRelativePath(parent) + "/children"; - String xml = httpClient.doRequest("GET", relativePath, String.class, Format.XML, null, null); - - return UntypedItemCollection.build(xml); - } - - @Override - public UntypedItem getItemUntyped(PlatformLayerKey key) throws PlatformLayerClientException { - String relativePath = buildRelativePath(key); - - String xml = httpClient.doRequest("GET", relativePath, String.class, Format.XML, null, null); - - UntypedItem item = UntypedItem.build(xml); - - return item; - } - - @Override - public JobDataList listJobs() throws PlatformLayerClientException { - String relativePath = "/jobs"; - JobDataList jobs = httpClient.doRequest("GET", relativePath, JobDataList.class, Format.XML, null, null); - - return jobs; - } - - @Override - public JobLog getJobLog(String jobId) throws PlatformLayerClientException { - String relativePath = "/jobs/" + jobId + "/log"; - JobLog log = httpClient.doRequest("GET", relativePath, JobLog.class, Format.XML, null, null); - - return log; - } - - @Override - public MetricInfoCollection listMetrics(PlatformLayerKey key) throws PlatformLayerClientException { - String relativePath = buildRelativePath(key) + "/metrics"; - - String retval = httpClient.doRequest("GET", relativePath, String.class, Format.XML, null, null); - MetricInfoCollection items; - try { - items = JaxbHelper.deserializeXmlObject(retval, MetricInfoCollection.class); - } catch (UnmarshalException e) { - throw new PlatformLayerClientException("Error parsing returned data", e); - } - return items; - } - - @Override - public MetricValues getMetric(PlatformLayerKey key, String metricKey) throws PlatformLayerClientException { - String relativePath = buildRelativePath(key) + "/metrics/" + metricKey; - - String retval = httpClient.doRequest("GET", relativePath, String.class, Format.XML, null, null); - MetricValues items; - try { - items = JaxbHelper.deserializeXmlObject(retval, MetricValues.class); - } catch (UnmarshalException e) { - throw new PlatformLayerClientException("Error parsing returned data", e); - } - return items; - } - - @Override - public JobData doAction(PlatformLayerKey key, String action) throws PlatformLayerClientException { - String relativePath = buildRelativePath(key) + "/actions"; - - if (action == null || action.isEmpty()) { - throw new IllegalArgumentException(); - } - - Action actionCommand = new Action(action); - - JobData retval = httpClient.doRequest("POST", relativePath, JobData.class, Format.XML, actionCommand, - Format.XML); - return retval; - } - - @Override - public ProjectId getProject() { - return projectId; - } - - // protected String buildRelativePath(ServiceType serviceType, ItemType itemType) { - // return urlEncode(serviceType.getKey()) + "/" + urlEncode(itemType.getKey()) + "/"; - // } - -} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/EndpointChooser.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/EndpointChooser.java new file mode 100644 index 000000000..d949f52ec --- /dev/null +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/EndpointChooser.java @@ -0,0 +1,38 @@ +package org.platformlayer; + +import java.net.InetAddress; + +import org.platformlayer.choice.ScoreChooser; +import org.platformlayer.core.model.EndpointInfo; + +public class EndpointChooser extends ScoreChooser { + + InetAddressChooser addressChooser; + + public EndpointChooser() { + super(true); + } + + @Override + protected Integer score(EndpointInfo candidate) { + InetAddress address = candidate.getAddress(); + + int score = 0; + if (addressChooser != null) { + score += addressChooser.score(address); + } + return score; + } + + public static EndpointChooser preferIpv4() { + EndpointChooser chooser = new EndpointChooser(); + chooser.addressChooser = InetAddressChooser.preferIpv4(); + return chooser; + } + + public static EndpointChooser any() { + EndpointChooser chooser = new EndpointChooser(); + return chooser; + } + +} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/EndpointInfo.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/EndpointInfo.java deleted file mode 100644 index f3e87c95c..000000000 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/EndpointInfo.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.platformlayer; - -import java.util.ArrayList; -import java.util.List; - -import org.platformlayer.core.model.Tag; -import org.platformlayer.core.model.Tags; - -import com.google.common.base.Objects; -import com.google.common.base.Splitter; -import com.google.common.collect.Lists; - -public class EndpointInfo { - - public EndpointInfo() { - } - - public EndpointInfo(String address, int publicPort) { - this.publicIp = address; - this.port = publicPort; - } - - public static List getEndpoints(Tags tags) { - List endpoints = Lists.newArrayList(); - - for (String publicEndpoint : tags.find(Tag.PUBLIC_ENDPOINT)) { - ArrayList components = Lists.newArrayList(Splitter.on(":").split(publicEndpoint)); - if (components.size() == 2) { - EndpointInfo info = new EndpointInfo(); - info.publicIp = components.get(0); - info.port = Integer.parseInt(components.get(1)); - - endpoints.add(info); - } else { - throw new IllegalStateException(); - } - } - return endpoints; - - } - - public static EndpointInfo findEndpoint(Tags tags, Integer port) { - for (EndpointInfo publicEndpoint : getEndpoints(tags)) { - if (publicEndpoint.matches(port)) { - return publicEndpoint; - } - } - return null; - } - - public String publicIp; - public Integer port; - - public boolean matches(Integer port) { - if (this.port == null || port == null || port == 0) { - return true; - } - if (!Objects.equal(port, this.port)) { - return false; - } - return true; - } - - public Tag toTag() { - return new Tag(Tag.PUBLIC_ENDPOINT, publicIp + ":" + port); - } - - @Override - public String toString() { - return publicIp + ":" + port; - } - -} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/Filter.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/Filter.java index 8127ad6ff..8680ded98 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/Filter.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/Filter.java @@ -1,6 +1,9 @@ package org.platformlayer; +import java.util.List; + import org.platformlayer.core.model.ItemBase; +import org.platformlayer.core.model.Tag; public abstract class Filter { public static final Filter EMPTY = null; @@ -14,4 +17,10 @@ public boolean matches(Object item) { } public abstract boolean matchesItem(T item); + + public static Filter and(Filter... filters) { + return new AndFilter(filters); + } + + public abstract List getRequiredTags(); } diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/HttpPlatformLayerClient.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/HttpPlatformLayerClient.java new file mode 100644 index 000000000..d1936bda5 --- /dev/null +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/HttpPlatformLayerClient.java @@ -0,0 +1,526 @@ +package org.platformlayer; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.PrintStream; +import java.util.List; +import java.util.Properties; + +import javax.xml.bind.UnmarshalException; + +import org.platformlayer.auth.Authenticator; +import org.platformlayer.auth.PlatformlayerAuthenticator; +import org.platformlayer.common.UntypedItem; +import org.platformlayer.common.UntypedItemCollection; +import org.platformlayer.core.model.Action; +import org.platformlayer.core.model.ItemBase; +import org.platformlayer.core.model.PlatformLayerKey; +import org.platformlayer.core.model.ServiceInfo; +import org.platformlayer.core.model.ServiceInfoCollection; +import org.platformlayer.core.model.Tag; +import org.platformlayer.core.model.TagChanges; +import org.platformlayer.core.model.Tags; +import org.platformlayer.federation.model.PlatformLayerConnectionConfiguration; +import org.platformlayer.http.HttpMethod; +import org.platformlayer.http.HttpStrategy; +import org.platformlayer.ids.ItemType; +import org.platformlayer.ids.ManagedItemId; +import org.platformlayer.ids.ProjectId; +import org.platformlayer.ids.ServiceType; +import org.platformlayer.jobs.model.JobData; +import org.platformlayer.jobs.model.JobDataList; +import org.platformlayer.jobs.model.JobExecutionList; +import org.platformlayer.jobs.model.JobLog; +import org.platformlayer.metrics.model.JsonMetricDataStream; +import org.platformlayer.metrics.model.MetricDataStream; +import org.platformlayer.metrics.model.MetricInfoCollection; +import org.platformlayer.metrics.model.MetricQuery; +import org.platformlayer.ops.OpsException; +import org.platformlayer.xml.JaxbHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fathomdb.properties.PropertyUtils; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import com.google.common.collect.Lists; +import com.google.common.io.Closeables; + +public class HttpPlatformLayerClient extends PlatformLayerClientBase { + public static final String SERVICE_PLATFORMLAYER = "platformlayer"; + + static final Logger log = LoggerFactory.getLogger(HttpPlatformLayerClient.class); + + List services; + + private final ProjectId projectId; + + private final PlatformLayerHttpTransport httpClient; + + private HttpPlatformLayerClient(TypedItemMapper mapper, PlatformLayerHttpTransport httpClient, ProjectId projectId) { + super(mapper); + + this.httpClient = httpClient; + this.projectId = projectId; + } + + public static HttpPlatformLayerClient buildUsingSavedConfiguration(HttpStrategy httpStrategy, String key) + throws IOException { + File credentialsFile = new File(System.getProperty("user.home") + File.separator + ".credentials" + + File.separator + key); + if (!credentialsFile.exists()) { + throw new FileNotFoundException("Credentials file not found: " + credentialsFile); + } + + Properties properties; + try { + properties = PropertyUtils.loadProperties(credentialsFile); + } catch (IOException e) { + throw new IOException("Error reading credentials file: " + credentialsFile, e); + } + + return buildUsingProperties(httpStrategy, properties); + } + + public static HttpPlatformLayerClient buildUsingConfiguration(HttpStrategy httpStrategy, + PlatformLayerConnectionConfiguration config) { + String project = config.tenant; + String server = config.authenticationEndpoint; + String username = config.username; + String secret = config.secret; + List authTrustKeys = config.authTrustKeys; + + Authenticator authenticator = new PlatformlayerAuthenticator(httpStrategy, username, secret, server, + authTrustKeys); + ProjectId projectId = new ProjectId(project); + + return build(httpStrategy, config.platformlayerEndpoint, authenticator, projectId, + config.platformlayerTrustKeys); + } + + public static HttpPlatformLayerClient buildUsingProperties(HttpStrategy httpStrategy, Properties properties) { + PlatformLayerConnectionConfiguration config = new PlatformLayerConnectionConfiguration(); + config.tenant = properties.getProperty("platformlayer.tenant"); + config.authenticationEndpoint = properties.getProperty("platformlayer.auth.url"); + config.username = properties.getProperty("platformlayer.username"); + config.secret = properties.getProperty("platformlayer.password"); + config.platformlayerEndpoint = properties.getProperty("platformlayer.url"); + + String trustKeys = properties.getProperty("platformlayer.ssl.keys", null); + if (!Strings.isNullOrEmpty(trustKeys)) { + config.platformlayerTrustKeys = Lists.newArrayList(Splitter.on(',').trimResults().split(trustKeys)); + } + + String authTrustKeys = properties.getProperty("platformlayer.auth.ssl.keys", null); + if (!Strings.isNullOrEmpty(authTrustKeys)) { + config.authTrustKeys = Lists.newArrayList(Splitter.on(',').trimResults().split(authTrustKeys)); + } + + return buildUsingConfiguration(httpStrategy, config); + } + + public static HttpPlatformLayerClient build(HttpStrategy httpStrategy, String platformlayerBaseUrl, + Authenticator authenticator, ProjectId projectId, List trustKeys) { + String url = platformlayerBaseUrl; + if (!url.endsWith("/")) { + url += "/"; + } + + TypedItemMapper mapper = null; + return new HttpPlatformLayerClient(mapper, new PlatformLayerHttpTransport(httpStrategy, url, authenticator, + trustKeys), projectId); + } + + @Override + public List listServices(boolean allowCache) throws PlatformLayerClientException { + if (!allowCache || services == null) { + ServiceInfoCollection ret = doRequest(HttpMethod.GET, "", ServiceInfoCollection.class, Format.XML, null, + null); + services = ret.services; + } + + return services; + } + + @Override + public void ensureLoggedIn() throws PlatformLayerAuthenticationException { + httpClient.getAuthenticationToken(); + } + + // public String createItem(ServiceType serviceType, ItemType itemType, String data, Format format) throws + // PlatformLayerClientException { + // String relativePath = buildRelativePath(serviceType, itemType, null); + // + // return httpClient.doRequest("POST", relativePath, String.class, data, format); + // } + + private T doRequest(HttpMethod method, String relativeUrl, Class retvalClass, Format acceptFormat, + Object sendData, Format sendDataFormat) throws PlatformLayerClientException { + if (relativeUrl.startsWith("/")) { + assert false; + relativeUrl = relativeUrl.substring(1); + } + + relativeUrl = projectId.getKey() + "/" + relativeUrl; + + return httpClient.doRequest(method, relativeUrl, retvalClass, acceptFormat, sendData, sendDataFormat); + } + + public UntypedItem putItem(ServiceType serviceType, ItemType itemType, ManagedItemId id, String data, + Format dataFormat) throws PlatformLayerClientException { + if (id == null) { + throw new IllegalArgumentException("id is required on a put"); + } + + String relativePath = buildRelativePath(serviceType, itemType, id); + + String xml = doRequest(HttpMethod.PUT, relativePath, String.class, Format.XML, data, dataFormat); + return UntypedItemXml.build(xml); + } + + @Override + public UntypedItem putItemByTag(PlatformLayerKey key, Tag uniqueTag, String data, Format dataFormat) + throws PlatformLayerClientException { + if (key.getItemId() == null) { + throw new IllegalArgumentException("id is required on a put"); + } + + String relativePath = buildRelativePath(key); + + if (uniqueTag != null) { + relativePath += "?unique=" + urlEncode(uniqueTag.getKey()); + } + + String xml = doRequest(HttpMethod.PUT, relativePath, String.class, Format.XML, data, dataFormat); + UntypedItem item = UntypedItemXml.build(xml); + + // PlatformLayerKey platformLayerKey = item.getPlatformLayerKey(); + // platformLayerKey = platformLayerKey.withId(new ManagedItemId(item.getId())); + // item.setPlatformLayerKey(platformLayerKey); + + return item; + } + + @Override + public UntypedItem putItem(PlatformLayerKey key, String data, Format dataFormat) + throws PlatformLayerClientException { + return putItem(key.getServiceType(), key.getItemType(), key.getItemId(), data, dataFormat); + } + + @Override + public String activateService(String serviceType, String data, Format dataFormat) + throws PlatformLayerClientException { + String relativePath = "authorizations/" + serviceType + "/"; + + return doRequest(HttpMethod.POST, relativePath, String.class, Format.XML, data, dataFormat); + } + + @Override + public String getActivation(String serviceType, Format format) throws PlatformLayerClientException { + String relativePath = "authorizations/" + serviceType + "/"; + + return doRequest(HttpMethod.GET, relativePath, String.class, format, null, null); + } + + @Override + public String getSshPublicKey(String serviceType) throws PlatformLayerClientException { + String relativePath = serviceType + "/sshkey"; + + return doRequest(HttpMethod.GET, relativePath, String.class, Format.TEXT, null, null); + } + + @Override + public String getSchema(String serviceType, Format format) throws PlatformLayerClientException { + String relativePath = serviceType + "/schema"; + + return doRequest(HttpMethod.GET, relativePath, String.class, format, null, null); + } + + // public T createItem(T item) throws PlatformLayerClientException { + // JaxbHelper jaxbHelper = toJaxbHelper(item); + // + // String xml = serialize(jaxbHelper, item); + // + // PlatformLayerKey key = toKey(jaxbHelper, item); + // + // String relativePath = buildRelativePath(key); + // + // String retval = httpClient.doRequest("POST", relativePath, String.class, xml, Format.XML); + // + // T created = deserializeItem((Class) item.getClass(), retval); + // + // setPlatformLayerKey(created, key); + // + // return created; + // } + + @Override + public Tags changeTags(PlatformLayerKey key, TagChanges tagChanges, Long ifVersion) + throws PlatformLayerClientException { + if (ifVersion != null) { + throw new UnsupportedOperationException(); + } else { + return changeTags(key.getServiceType(), key.getItemType(), key.getItemId(), tagChanges); + } + } + + public Tags changeTags(ServiceType serviceType, ItemType itemType, ManagedItemId id, TagChanges tagChanges) + throws PlatformLayerClientException { + String url = buildRelativePath(serviceType, itemType, id) + "/tags"; + Tags retval = doRequest(HttpMethod.POST, url, Tags.class, Format.XML, tagChanges, Format.XML); + return retval; + } + + // public void deleteItem(T item) throws PlatformLayerClientException { + // JaxbHelper jaxbHelper = toJaxbHelper(item); + // + // PlatformLayerKey key = toKey(jaxbHelper, item); + // deleteItem(key); + // } + + @Override + public JobData deleteItem(PlatformLayerKey key) throws PlatformLayerClientException { + String relativePath = buildRelativePath(key); + + JobData retval = doRequest(HttpMethod.DELETE, relativePath, JobData.class, Format.XML, null, null); + return retval; + } + + // public List listItems(Class clazz) throws PlatformLayerClientException { + // return listItems(clazz, (Filter) null); + // } + // + // public List listItems(Class clazz, Tag tag) throws PlatformLayerClientException { + // return listItems(clazz, Filter.byTag(tag)); + // } + + // public List listItems(Class clazz, Filter filter) throws PlatformLayerClientException { + // JaxbHelper jaxbHelper = toJaxbHelper(clazz, ManagedItemCollection.class); + // PlatformLayerKey key = toKey(jaxbHelper); + // + // String xml = doListItemsRequest(key); + // + // ManagedItemCollection items; + // try { + // items = jaxbHelper.deserialize(new StringReader(xml), ManagedItemCollection.class); + // } catch (UnmarshalException e) { + // throw new PlatformLayerClientException("Error parsing returned data", e); + // } + // + // if (filter != null) { + // // TODO: Do filtering server-side + // List filtered = Lists.newArrayList(); + // for (T item : items.items) { + // if (filter.matches(item)) { + // filtered.add(item); + // } + // } + // return filtered; + // } else { + // return items.items; + // } + // } + + // public T getItem(Class clazz, PlatformLayerKey key) throws PlatformLayerClientException { + // if (key.getHost() != null) + // throw new UnsupportedOperationException(); + // + // String relativePath = buildRelativePath(key); + // T item = httpClient.doRequest(HttpMethod.GET, relativePath, clazz, Format.XML, null, Format.XML); + // + // setPlatformLayerKey(item, key); + // + // return item; + // } + + // private void setPlatformLayerKey(T item, PlatformLayerKey key) { + // if (item instanceof ItemBase) { + // ((ItemBase) item).setKey(key); + // } else { + // throw new IllegalStateException(); + // } + // } + + private String doListItemsRequest(PlatformLayerKey path) throws PlatformLayerClientException { + String relativePath = buildRelativePath(path); + String retval = doRequest(HttpMethod.GET, relativePath, String.class, Format.XML, null, null); + return retval; + } + + @Override + public UntypedItemCollection listItemsUntyped(PlatformLayerKey path) throws PlatformLayerClientException { + String xml = doListItemsRequest(path); + + return UntypedItemXmlCollection.build(xml); + } + + private String doListRootsRequest() throws PlatformLayerClientException { + String relativePath = "roots"; + String retval = doRequest(HttpMethod.GET, relativePath, String.class, Format.XML, null, null); + return retval; + } + + @Override + public UntypedItemCollection listRoots() throws PlatformLayerClientException { + String xml = doListRootsRequest(); + + return UntypedItemXmlCollection.build(xml); + } + + @Override + public UntypedItemCollection listChildren(PlatformLayerKey parent, boolean includeDeleted) + throws PlatformLayerClientException { + String relativePath = buildRelativePath(parent) + "/children"; + if (includeDeleted) { + relativePath += "?deleted=1"; + } + String xml = doRequest(HttpMethod.GET, relativePath, String.class, Format.XML, null, null); + + return UntypedItemXmlCollection.build(xml); + } + + @Override + public UntypedItem getItemUntyped(PlatformLayerKey key, Format format) throws PlatformLayerClientException { + String relativePath = buildRelativePath(key); + + String data = doRequest(HttpMethod.GET, relativePath, String.class, format, null, null); + + UntypedItem item; + switch (format) { + case XML: + item = UntypedItemXml.build(data); + break; + + case JSON: + item = UntypedItemJson.build(data); + break; + + default: + throw new IllegalArgumentException("Format not supported"); + } + + return item; + + } + + @Override + public JobDataList listJobs(PlatformLayerKey key) throws PlatformLayerClientException { + String relativePath = buildRelativePath(key) + "/jobs"; + + JobDataList jobs = doRequest(HttpMethod.GET, relativePath, JobDataList.class, Format.XML, null, null); + return jobs; + } + + @Override + public JobDataList listJobs() throws PlatformLayerClientException { + String relativePath = "jobs"; + JobDataList jobs = doRequest(HttpMethod.GET, relativePath, JobDataList.class, Format.XML, null, null); + + return jobs; + } + + @Override + public JobExecutionList listJobExecutions() throws PlatformLayerClientException { + String relativePath = "jobs/runs"; + JobExecutionList jobs = doRequest(HttpMethod.GET, relativePath, JobExecutionList.class, Format.XML, null, null); + + return jobs; + } + + @Override + public MetricInfoCollection listMetrics(PlatformLayerKey key) throws PlatformLayerClientException { + String relativePath = buildRelativePath(key) + "/metrics"; + + String retval = doRequest(HttpMethod.GET, relativePath, String.class, Format.XML, null, null); + MetricInfoCollection items; + try { + items = JaxbHelper.deserializeXmlObject(retval, MetricInfoCollection.class); + } catch (UnmarshalException e) { + throw new PlatformLayerClientException("Error parsing returned data", e); + } + return items; + } + + @Override + public MetricDataStream getMetric(MetricQuery query) throws PlatformLayerClientException { + String relativePath = buildRelativePath(query.item) + "/metrics"; + + StreamingResponse response = doRequest(HttpMethod.POST, relativePath, StreamingResponse.class, Format.JSON, + query, Format.XML); + MetricDataStream dataStream; + try { + dataStream = JsonMetricDataStream.build(response.getResponseStream()); + response = null; // Don't close yet + } catch (IOException e) { + throw new PlatformLayerClientException("Error parsing returned data", e); + } finally { + Closeables.closeQuietly(response); + } + return dataStream; + } + + @Override + public JobData doAction(PlatformLayerKey key, Action action) throws PlatformLayerClientException { + String relativePath = buildRelativePath(key) + "/actions"; + + JobData retval = doRequest(HttpMethod.POST, relativePath, JobData.class, Format.XML, action, Format.XML); + return retval; + } + + @Override + public JobData doAction(PlatformLayerKey key, String action, Format dataFormat) throws PlatformLayerClientException { + String relativePath = buildRelativePath(key) + "/actions"; + + JobData retval = doRequest(HttpMethod.POST, relativePath, JobData.class, Format.XML, action, dataFormat); + return retval; + } + + @Override + public ProjectId getProject() { + return projectId; + } + + public void setDebug(PrintStream debug) { + httpClient.setDebug(debug); + } + + @Override + public PlatformLayerEndpointInfo getEndpointInfo(PlatformLayerKey item) { + return httpClient.getEndpointInfo(projectId); + } + + @Override + public JobLog getJobExecutionLog(String jobId, String executionId) throws PlatformLayerClientException { + String relativePath = "jobs/" + jobId + "/runs/" + executionId + "/log"; + JobLog jobLog = doRequest(HttpMethod.GET, relativePath, JobLog.class, Format.XML, null, null); + return jobLog; + } + + @Override + public JobExecutionList listJobExecutions(String jobId) throws PlatformLayerClientException { + String relativePath = "jobs/" + jobId + "/runs"; + JobExecutionList executions = doRequest(HttpMethod.GET, relativePath, JobExecutionList.class, Format.XML, null, + null); + return executions; + } + + @Override + public T putItem(T item) throws OpsException { + JaxbHelper jaxbHelper = PlatformLayerClientBase.toJaxbHelper(item); + + String xml = PlatformLayerClientBase.serialize(jaxbHelper, item); + + PlatformLayerKey key = PlatformLayerClientBase.toKey(jaxbHelper, item, listServices(true)); + + UntypedItem created = putItem(key, xml, Format.XML); + + Class itemClass = (Class) item.getClass(); + return promoteToTyped(created, itemClass); + } + + // protected String buildRelativePath(ServiceType serviceType, ItemType itemType) { + // return urlEncode(serviceType.getKey()) + "/" + urlEncode(itemType.getKey()) + "/"; + // } + +} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/InetAddressChooser.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/InetAddressChooser.java new file mode 100644 index 000000000..5e457d187 --- /dev/null +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/InetAddressChooser.java @@ -0,0 +1,35 @@ +package org.platformlayer; + +import java.net.Inet4Address; +import java.net.InetAddress; + +import org.platformlayer.choice.ScoreChooser; + +public class InetAddressChooser extends ScoreChooser { + final int scoreIpv4; + final int scoreIpv6; + + public InetAddressChooser(int scoreIpv4, int scoreIpv6) { + super(true); + this.scoreIpv4 = scoreIpv4; + this.scoreIpv6 = scoreIpv6; + } + + @Override + protected Integer score(InetAddress address) { + int score = 0; + score += address instanceof Inet4Address ? scoreIpv4 : scoreIpv6; + return score; + } + + public static InetAddressChooser preferIpv4() { + InetAddressChooser chooser = new InetAddressChooser(100, 0); + return chooser; + } + + public static InetAddressChooser preferIpv6() { + InetAddressChooser chooser = new InetAddressChooser(0, 100); + return chooser; + } + +} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerClient.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerClient.java index 9fb079d5a..8eac50fe1 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerClient.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerClient.java @@ -1,7 +1,12 @@ package org.platformlayer; import java.util.Collection; +import java.util.List; +import org.platformlayer.common.UntypedItem; +import org.platformlayer.common.UntypedItemCollection; +import org.platformlayer.core.model.Action; +import org.platformlayer.core.model.ItemBase; import org.platformlayer.core.model.PlatformLayerKey; import org.platformlayer.core.model.ServiceInfo; import org.platformlayer.core.model.Tag; @@ -9,13 +14,19 @@ import org.platformlayer.core.model.Tags; import org.platformlayer.ids.ProjectId; import org.platformlayer.jobs.model.JobData; +import org.platformlayer.jobs.model.JobDataList; +import org.platformlayer.jobs.model.JobExecutionList; import org.platformlayer.jobs.model.JobLog; +import org.platformlayer.metrics.model.MetricDataStream; import org.platformlayer.metrics.model.MetricInfoCollection; -import org.platformlayer.metrics.model.MetricValues; +import org.platformlayer.metrics.model.MetricQuery; +import org.platformlayer.ops.OpsException; public interface PlatformLayerClient { // Actions - public JobData doAction(PlatformLayerKey key, String action) throws PlatformLayerClientException; + public JobData doAction(PlatformLayerKey key, Action action) throws PlatformLayerClientException; + + public JobData doAction(PlatformLayerKey key, String action, Format dataFormat) throws PlatformLayerClientException; // Item CRUD // public Iterable listItems(Class clazz) throws PlatformLayerClientException; @@ -36,32 +47,44 @@ public interface PlatformLayerClient { public UntypedItem putItem(PlatformLayerKey key, String data, Format dataFormat) throws PlatformLayerClientException; + public T putItem(T item) throws OpsException; + public UntypedItem putItemByTag(PlatformLayerKey key, Tag uniqueTag, String data, Format dataFormat) throws PlatformLayerClientException; + public T putItemByTag(T item, Tag uniqueTag) throws OpsException; + // public T putItem(T item) throws PlatformLayerClientException; - public void deleteItem(PlatformLayerKey key) throws PlatformLayerClientException; + public JobData deleteItem(PlatformLayerKey key) throws PlatformLayerClientException; // Item Crud - Untyped - public UntypedItem getItemUntyped(PlatformLayerKey key) throws PlatformLayerClientException; + public UntypedItem getItemUntyped(PlatformLayerKey key, Format format) throws PlatformLayerClientException; - public Iterable listItemsUntyped(PlatformLayerKey path) throws PlatformLayerClientException; + public UntypedItemCollection listItemsUntyped(PlatformLayerKey path) throws PlatformLayerClientException; - public Iterable listRoots() throws PlatformLayerClientException; + public List listItems(Class clazz) throws PlatformLayerClientException, OpsException; - public Iterable listChildren(PlatformLayerKey parent) throws PlatformLayerClientException; + public UntypedItemCollection listRoots() throws PlatformLayerClientException; + + public UntypedItemCollection listChildren(PlatformLayerKey parent, boolean includeDeleted) + throws PlatformLayerClientException; + + public List listChildrenTyped(PlatformLayerKey parent, boolean includeDeleted) throws OpsException; // Tags - public Tags changeTags(PlatformLayerKey key, TagChanges tagChanges) throws PlatformLayerClientException; + public Tags changeTags(PlatformLayerKey key, TagChanges tagChanges, Long ifVersion) + throws PlatformLayerClientException; // Jobs - public Iterable listJobs() throws PlatformLayerClientException; + public JobDataList listJobs() throws PlatformLayerClientException; - public JobLog getJobLog(String jobId) throws PlatformLayerClientException; + public JobDataList listJobs(PlatformLayerKey target) throws PlatformLayerClientException; + + public JobLog getJobExecutionLog(String jobId, String executionId) throws PlatformLayerClientException; // Metrics - public MetricValues getMetric(PlatformLayerKey key, String metricKey) throws PlatformLayerClientException; + public MetricDataStream getMetric(MetricQuery query) throws PlatformLayerClientException; public MetricInfoCollection listMetrics(PlatformLayerKey key) throws PlatformLayerClientException; @@ -83,4 +106,16 @@ public UntypedItem putItemByTag(PlatformLayerKey key, Tag uniqueTag, String data public ProjectId getProject(); + public PlatformLayerEndpointInfo getEndpointInfo(PlatformLayerKey item); + + public JobExecutionList listJobExecutions(String jobId) throws PlatformLayerClientException; + + public T findItem(PlatformLayerKey key, Class itemClass) throws OpsException; + + public T findItem(PlatformLayerKey key) throws OpsException; + + public JobExecutionList listJobExecutions() throws PlatformLayerClientException; + + public Tags getItemTags(PlatformLayerKey key) throws PlatformLayerClientException; + } diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerClientBase.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerClientBase.java index 12ac14dbe..123c968c3 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerClientBase.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerClientBase.java @@ -9,16 +9,24 @@ import java.util.List; import javax.xml.bind.JAXBException; +import javax.xml.bind.UnmarshalException; +import org.platformlayer.common.UntypedItem; +import org.platformlayer.common.UntypedItemCollection; +import org.platformlayer.core.model.ItemBase; +import org.platformlayer.core.model.ManagedItemCollection; import org.platformlayer.core.model.PlatformLayerKey; import org.platformlayer.core.model.ServiceInfo; +import org.platformlayer.core.model.Tag; +import org.platformlayer.core.model.TagChanges; +import org.platformlayer.core.model.Tags; import org.platformlayer.ids.FederationKey; import org.platformlayer.ids.ItemType; import org.platformlayer.ids.ManagedItemId; import org.platformlayer.ids.ProjectId; import org.platformlayer.ids.ServiceType; +import org.platformlayer.ops.OpsException; import org.platformlayer.xml.JaxbHelper; -import org.platformlayer.xml.UnmarshalException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,9 +35,13 @@ public abstract class PlatformLayerClientBase implements PlatformLayerClient { static final Logger log = LoggerFactory.getLogger(PlatformLayerClientBase.class); - static Class[] objectFactories = { org.platformlayer.service.dns.v1.ObjectFactory.class, - org.platformlayer.service.imagefactory.v1.ObjectFactory.class, - org.platformlayer.service.instancesupervisor.v1.ObjectFactory.class, }; + static Class[] objectFactories = {}; + + private final TypedItemMapper mapper; + + public PlatformLayerClientBase(TypedItemMapper mapper) { + this.mapper = mapper; + } public static JaxbHelper toJaxbHelper(Class clazz, Class... extraClasses) { List> extraClassesLists = Arrays.asList(extraClasses); @@ -172,4 +184,99 @@ public static String urlEncode(String s) { throw new IllegalStateException("UTF-8 Encoding not found", e); } } + + @Override + public List listItems(Class clazz) throws OpsException { + JaxbHelper jaxbHelper = PlatformLayerClientBase.toJaxbHelper(clazz, ManagedItemCollection.class); + PlatformLayerKey path = PlatformLayerClientBase.toKey(jaxbHelper, null, listServices(true)); + + UntypedItemCollection untypedItems = listItemsUntyped(path); + + List items = Lists.newArrayList(); + + for (UntypedItem untypedItem : untypedItems.getItems()) { + T item = promoteToTyped(untypedItem, clazz); + items.add(item); + } + + return items; + } + + public T promoteToTyped(UntypedItem untypedItem) throws PlatformLayerClientException { + if (mapper == null) { + throw new UnsupportedOperationException(); + } + try { + return mapper.promoteToTyped(untypedItem); + } catch (OpsException e) { + throw new PlatformLayerClientException("Error parsing item", e); + } + } + + public T promoteToTyped(UntypedItem untypedItem, Class itemClass) throws PlatformLayerClientException { + if (mapper == null) { + throw new UnsupportedOperationException(); + } + try { + return mapper.promoteToTyped(untypedItem, itemClass); + } catch (OpsException e) { + throw new PlatformLayerClientException("Error parsing item", e); + } + } + + @Override + public T putItemByTag(T item, Tag uniqueTag) throws OpsException { + JaxbHelper jaxbHelper = PlatformLayerClientBase.toJaxbHelper(item); + + String xml = PlatformLayerClientBase.serialize(jaxbHelper, item); + PlatformLayerKey key = PlatformLayerClientBase.toKey(jaxbHelper, item, listServices(true)); + + UntypedItem ret = putItemByTag(key, uniqueTag, xml, Format.XML); + Class itemClass = (Class) item.getClass(); + return promoteToTyped(ret, itemClass); + } + + @Override + public List listChildrenTyped(PlatformLayerKey parent, boolean includeDeleted) throws OpsException { + List ret = Lists.newArrayList(); + for (UntypedItem item : listChildren(parent, includeDeleted).getItems()) { + ItemBase typedItem = promoteToTyped(item); + ret.add(typedItem); + } + return ret; + } + + @Override + public T findItem(PlatformLayerKey key, Class itemClass) throws OpsException { + UntypedItem itemUntyped = getItemUntyped(key, Format.XML); + if (itemUntyped == null) { + return null; + } + + return promoteToTyped(itemUntyped, itemClass); + } + + @Override + public T findItem(PlatformLayerKey key) throws OpsException { + UntypedItem itemUntyped = getItemUntyped(key, Format.XML); + if (itemUntyped == null) { + return null; + } + + return promoteToTyped(itemUntyped); + } + + public Tags changeTags(PlatformLayerKey key, TagChanges tagChanges) throws PlatformLayerClientException { + return changeTags(key, tagChanges, null); + } + + @Override + public Tags getItemTags(PlatformLayerKey key) throws PlatformLayerClientException { + UntypedItem itemUntyped = getItemUntyped(key, Format.XML); + if (itemUntyped == null) { + return null; + } + return itemUntyped.getTags(); + } + } diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerClientException.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerClientException.java index b394fdee3..ff040a04d 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerClientException.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerClientException.java @@ -17,10 +17,10 @@ public PlatformLayerClientException(String message, String serviceFault, int htt this.httpResponseCode = httpResponseCode; } - public PlatformLayerClientException() { - this.serviceFault = null; - this.httpResponseCode = null; - } + // public PlatformLayerClientException() { + // this.serviceFault = null; + // this.httpResponseCode = null; + // } public PlatformLayerClientException(String message, Throwable cause) { super(message, cause); diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerClientNotFoundException.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerClientNotFoundException.java new file mode 100644 index 000000000..621373a75 --- /dev/null +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerClientNotFoundException.java @@ -0,0 +1,19 @@ +package org.platformlayer; + +import java.net.URI; + +public class PlatformLayerClientNotFoundException extends PlatformLayerClientException { + private static final long serialVersionUID = 1L; + + private final URI url; + + public PlatformLayerClientNotFoundException(String message, int httpCode, URI url) { + super(message, httpCode); + this.url = url; + } + + public URI getUrl() { + return url; + } + +} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerEndpointInfo.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerEndpointInfo.java new file mode 100644 index 000000000..a3fd0a1ac --- /dev/null +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerEndpointInfo.java @@ -0,0 +1,39 @@ +package org.platformlayer; + +import java.util.List; + +import org.platformlayer.auth.Authenticator; +import org.platformlayer.ids.ProjectId; + +public class PlatformLayerEndpointInfo { + final Authenticator authenticator; + final String platformlayerBaseUrl; + final ProjectId projectId; + final List trustKeys; + + public PlatformLayerEndpointInfo(Authenticator authenticator, String platformlayerBaseUrl, ProjectId projectId, + List trustKeys) { + super(); + this.authenticator = authenticator; + this.platformlayerBaseUrl = platformlayerBaseUrl; + this.projectId = projectId; + this.trustKeys = trustKeys; + } + + public Authenticator getAuthenticator() { + return authenticator; + } + + public String getPlatformlayerBaseUrl() { + return platformlayerBaseUrl; + } + + public ProjectId getProjectId() { + return projectId; + } + + public List getTrustKeys() { + return trustKeys; + } + +} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerHttpClient.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerHttpClient.java deleted file mode 100644 index cd77aecbf..000000000 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerHttpClient.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.platformlayer; - -import java.net.URI; -import java.net.URISyntaxException; - -import org.platformlayer.auth.AuthenticationToken; -import org.platformlayer.auth.Authenticator; -import org.platformlayer.auth.OpenstackAuthenticationException; -import org.platformlayer.exceptions.OpenstackClientConnectionException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -class PlatformLayerHttpClient { - static final Logger log = LoggerFactory.getLogger(PlatformLayerHttpClient.class); - - final Authenticator authClient; - - public PlatformLayerHttpClient(Authenticator authenticator) { - this.authClient = authenticator; - } - - private static final long SLEEP_BETWEEN_RETRIES = 200; - - public static final Integer HTTP_500_ERROR = new Integer(500); - - public AuthenticationToken getAuthenticationToken() throws PlatformLayerAuthenticationException { - try { - return authClient.getAuthenticationToken(); - } catch (OpenstackAuthenticationException e) { - throw new PlatformLayerAuthenticationException("Error authenticating", e); - } - } - - protected T doSimpleRequest(String relativePath, Class retvalClass, Format format) - throws PlatformLayerClientException { - return doRequest("GET", relativePath, retvalClass, format, null, null); - } - - private String getPlatformLayerEndpoint() throws PlatformLayerClientException { - String url = getAuthenticationToken().getServiceUrl(DirectPlatformLayerClient.SERVICE_PLATFORMLAYER); - if (url == null) { - throw new PlatformLayerClientException("PlatformLayer endpoint not found"); - } - return url; - } - - private URI buildUri(String relativePath) throws PlatformLayerClientException { - String urlString = getPlatformLayerEndpoint(); - if (!urlString.endsWith("/") && !relativePath.startsWith("/")) { - urlString += "/"; - } - urlString += relativePath; - - URI uri; - try { - uri = new URI(urlString); - } catch (URISyntaxException e) { - throw new PlatformLayerClientException("Error building openstack URI: " + urlString, e); - } - - String host = uri.getHost(); - if (host.equals("0.0.0.0")) { - host = authClient.getHost(); - try { - uri = new URI(uri.getScheme(), uri.getUserInfo(), host, uri.getPort(), uri.getPath(), uri.getQuery(), - uri.getFragment()); - } catch (URISyntaxException e) { - throw new IllegalStateException("Error building URI", e); - } - } - return uri; - } - - protected T doRequest(String method, String relativePath, Class retvalClass, Format acceptFormat, - Object sendData, Format sendDataFormat) throws PlatformLayerClientException { - int maxRetries = 1; - for (int i = 1; i <= maxRetries; i++) { - PlatformLayerHttpRequest request = new PlatformLayerHttpRequest(this, method, buildUri(relativePath)); - try { - if (i == maxRetries) { - return request.doRequest(retvalClass, acceptFormat, sendData, sendDataFormat); - } else { - try { - return request.doRequest(retvalClass, acceptFormat, sendData, sendDataFormat); - } catch (OpenstackAuthenticationException e) { - log.warn("Reauthorizing after auth error", e); - authClient.clearAuthenticationToken(); - } catch (OpenstackClientConnectionException e) { - log.warn("Retrying after connection error", e); - } catch (PlatformLayerClientException e) { - if (HTTP_500_ERROR.equals(e.getHttpResponseCode())) { - log.warn("Retrying after 500 error from Openstack", e); - } else { - log.info("Response code = " + e.getHttpResponseCode()); - throw e; - } - } - - try { - Thread.sleep(SLEEP_BETWEEN_RETRIES); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - } finally { - IoUtils.safeClose(request); - } - } - - throw new IllegalStateException(); // Unreachable, but the compiler doesn't know that - } -} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerHttpRequest.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerHttpRequest.java index a2b9671e4..7fc3787c6 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerHttpRequest.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerHttpRequest.java @@ -3,40 +3,59 @@ import java.io.Closeable; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; +import java.io.PrintStream; import java.net.ConnectException; import java.net.URI; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.KeyManager; +import javax.net.ssl.TrustManager; import javax.xml.bind.JAXBException; -import javax.xml.stream.XMLStreamException; -import javax.xml.transform.TransformerException; +import javax.xml.bind.UnmarshalException; -import org.codehaus.jettison.json.JSONException; -import org.openstack.utils.Utf8; -import org.platformlayer.http.SimpleHttpRequest; -import org.platformlayer.http.SimpleHttpRequest.SimpleHttpResponse; +import org.platformlayer.http.HttpMethod; +import org.platformlayer.http.HttpRequest; +import org.platformlayer.http.HttpResponse; +import org.platformlayer.http.SslConfiguration; +import org.platformlayer.rest.Utf8StringByteSource; import org.platformlayer.xml.JaxbHelper; import org.platformlayer.xml.JsonHelper; -import org.platformlayer.xml.UnmarshalException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.fathomdb.Casts; +import com.fathomdb.crypto.ssl.AcceptAllHostnameVerifier; +import com.fathomdb.crypto.ssl.PublicKeyTrustManager; +import com.fathomdb.io.IoUtils; + class PlatformLayerHttpRequest implements Closeable { - static final Logger log = LoggerFactory.getLogger(PlatformLayerHttpRequest.class); + private static final Logger log = LoggerFactory.getLogger(PlatformLayerHttpRequest.class); - final PlatformLayerHttpClient client; - final SimpleHttpRequest httpRequest; - SimpleHttpResponse response; + final PlatformLayerHttpTransport client; + final HttpRequest httpRequest; + HttpResponse response; - public PlatformLayerHttpRequest(PlatformLayerHttpClient client, String method, URI uri) - throws PlatformLayerClientException { + PrintStream debug; + + public PlatformLayerHttpRequest(PlatformLayerHttpTransport client, HttpMethod method, URI uri, + List trustKeys) throws PlatformLayerClientException { this.client = client; - try { - this.httpRequest = SimpleHttpRequest.build(method, uri); - } catch (IOException e) { - throw new PlatformLayerClientException("Error building http request " + method + " " + uri, e); + + KeyManager keyManager = null; + TrustManager trustManager = null; + HostnameVerifier hostnameVerifier = null; + + if (trustKeys != null) { + trustManager = new PublicKeyTrustManager(trustKeys); + hostnameVerifier = new AcceptAllHostnameVerifier(); } + + SslConfiguration sslConfiguration = new SslConfiguration(keyManager, trustManager, hostnameVerifier); + + this.httpRequest = client.getHttpStrategy().buildConfiguration(sslConfiguration).buildRequest(method, uri); } void populateHttpRequest(Format acceptFormat, Format contentFormat) throws PlatformLayerClientException { @@ -77,7 +96,7 @@ void populateHttpRequest(Format acceptFormat, Format contentFormat) throws Platf this.client.getAuthenticationToken().populateRequest(httpRequest); } - SimpleHttpResponse getResponse() throws IOException { + HttpResponse getResponse() throws IOException { if (response == null) { response = httpRequest.doRequest(); } @@ -100,30 +119,44 @@ InputStream getErrorStream() throws IOException { return getResponse().getErrorStream(); } - OutputStream getOutputStream() throws IOException { - return httpRequest.getOutputStream(); - } - public T doRequest(Class retvalClass, Format acceptFormat, Object sendData, Format sendDataFormat) throws PlatformLayerClientException { try { populateHttpRequest(acceptFormat, sendDataFormat); + if (debug != null) { + debug.println("Request: " + httpRequest); + } + if (sendData != null) { if (sendData instanceof String) { + if (debug != null) { + debug.println("Data: " + sendData); + } + String sendDataString = (String) sendData; - OutputStreamWriter writer = Utf8.openWriter(getOutputStream()); - writer.write(sendDataString); - writer.flush(); + httpRequest.setRequestContent(new Utf8StringByteSource(sendDataString)); } else { switch (sendDataFormat) { case XML: + if (debug != null) { + debug.println("Data: [XML Content]"); + } + JaxbHelper jaxbHelper = JaxbHelper.get(sendData.getClass()); - jaxbHelper.marshal(sendData, false, getOutputStream()); + String xml = jaxbHelper.marshal(sendData, false); + httpRequest.setRequestContent(new Utf8StringByteSource(xml)); + // jaxbHelper.marshal(sendData, false, getOutputStream()); break; case JSON: + if (debug != null) { + debug.println("Data: [JSON Content]"); + } + JsonHelper jsonHelper = JsonHelper.build(sendData.getClass()); - jsonHelper.marshal(sendData, false, getOutputStream()); + String json = jsonHelper.marshal(sendData, false); + httpRequest.setRequestContent(new Utf8StringByteSource(json)); + // jsonHelper.marshal(sendData, false, getOutputStream()); break; default: throw new IllegalStateException(); @@ -134,13 +167,14 @@ public T doRequest(Class retvalClass, Format acceptFormat, Object sendDat throw new PlatformLayerClientException("Error while building request", e); } catch (IOException e) { throw new PlatformLayerClientException("Error while building request", e); - } catch (XMLStreamException e) { - throw new PlatformLayerClientException("Error while building request", e); - } catch (TransformerException e) { - throw new PlatformLayerClientException("Error while building request", e); - } catch (JSONException e) { - throw new PlatformLayerClientException("Error while building request", e); } + // catch (XMLStreamException e) { + // throw new PlatformLayerClientException("Error while building request", e); + // } catch (TransformerException e) { + // throw new PlatformLayerClientException("Error while building request", e); + // } catch (JSONException e) { + // throw new PlatformLayerClientException("Error while building request", e); + // } try { processHttpResponseCode(getResponse()); @@ -152,11 +186,21 @@ public T doRequest(Class retvalClass, Format acceptFormat, Object sendDat String text = null; if (is != null) { - text = IoUtils.readAll(Utf8.openReader(is)); + text = IoUtils.readAll(is); + } + + if (debug != null) { + debug.println("Response: " + text); } - return CastUtils.as(text, retvalClass); + return Casts.as(text, retvalClass); + } else if (StreamingResponse.class.equals(retvalClass)) { + return Casts.as(new StreamingResponse(getResponse()), retvalClass); } else { + if (debug != null) { + debug.println("Response: XML/JSON content"); + } + InputStream is = getInputStream(); return JaxbHelper.deserializeXmlObject(is, retvalClass, true); @@ -170,10 +214,27 @@ public T doRequest(Class retvalClass, Format acceptFormat, Object sendDat } } - private void processHttpResponseCode(SimpleHttpResponse response) throws PlatformLayerClientException, IOException { + private void processHttpResponseCode(HttpResponse response) throws PlatformLayerClientException, IOException { // Send the HTTP request int httpResponseCode = response.getHttpResponseCode(); + if (debug != null) { + debug.println("Response: " + response); + + Map> headers = response.getHeaderFields(); + for (Entry> entry : headers.entrySet()) { + String key = entry.getKey(); + if (key == null) { + // Ignore entry "key=null, value=HTTP/1.1 200 OK" + continue; + } + + for (String value : entry.getValue()) { + debug.println(key + ": " + value); + } + } + } + switch (httpResponseCode) { case 200: // OK case 201: // Created @@ -187,8 +248,8 @@ private void processHttpResponseCode(SimpleHttpResponse response) throws Platfor break; case 401: throw new PlatformLayerAuthenticationException("Not authorized (or authorization timed out)"); - // case 404: - // throw new PlatformLayerClientNotFoundException("Not found", httpRequest.getUrl()); + case 404: + throw new PlatformLayerClientNotFoundException("Not found", 404, httpRequest.getUrl()); case 500: throw buildExceptionFromErrorStream(httpResponseCode); @@ -203,7 +264,7 @@ private PlatformLayerClientException buildExceptionFromErrorStream(int httpRespo try { errorStream = getErrorStream(); if (errorStream != null) { - errorText = IoUtils.readAll(Utf8.openReader(errorStream)); + errorText = IoUtils.readAll(errorStream); } } catch (IOException e) { log.warn("Could not read error response from request", e); diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerHttpTransport.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerHttpTransport.java new file mode 100644 index 000000000..4780cb413 --- /dev/null +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/PlatformLayerHttpTransport.java @@ -0,0 +1,160 @@ +package org.platformlayer; + +import java.io.PrintStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; + +import org.platformlayer.auth.AuthenticationToken; +import org.platformlayer.auth.Authenticator; +import org.platformlayer.auth.PlatformlayerAuthenticationClientException; +import org.platformlayer.exceptions.OpenstackClientConnectionException; +import org.platformlayer.http.HttpMethod; +import org.platformlayer.http.HttpStrategy; +import org.platformlayer.ids.ProjectId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.io.Closeables; + +class PlatformLayerHttpTransport { + static final Logger log = LoggerFactory.getLogger(PlatformLayerHttpTransport.class); + + final Authenticator authClient; + PrintStream debug = null; + + final String platformlayerEndpoint; + + final List trustKeys; + + final HttpStrategy httpStrategy; + + public PlatformLayerHttpTransport(HttpStrategy httpStrategy, String platformlayerEndpoint, + Authenticator authClient, List trustKeys) { + this.httpStrategy = httpStrategy; + this.platformlayerEndpoint = platformlayerEndpoint; + this.authClient = authClient; + this.trustKeys = trustKeys; + } + + private static final long SLEEP_BETWEEN_RETRIES = 200; + + public static final Integer HTTP_500_ERROR = new Integer(500); + + public AuthenticationToken getAuthenticationToken() throws PlatformLayerAuthenticationException { + try { + return authClient.getAuthenticationToken(); + } catch (PlatformlayerAuthenticationClientException e) { + throw new PlatformLayerAuthenticationException("Error authenticating", e); + } + } + + // private String getPlatformLayerEndpoint() throws PlatformLayerClientException { + // return platformlayerEndpoint; + // } + + // String url = getAuthenticationToken().getServiceUrl(DirectPlatformLayerClient.SERVICE_PLATFORMLAYER); + // if (url == null) { + // throw new PlatformLayerClientException("PlatformLayer endpoint not found"); + // } + // return url; + // } + + private URI buildUri(String relativePath) throws PlatformLayerClientException { + if (relativePath.startsWith("/")) { + relativePath = relativePath.substring(1); + } + + String urlString = platformlayerEndpoint; + if (!urlString.endsWith("/")) { + urlString += "/"; + } + urlString += relativePath; + + URI uri; + try { + uri = new URI(urlString); + } catch (URISyntaxException e) { + throw new PlatformLayerClientException("Error building openstack URI: " + urlString, e); + } + + String host = uri.getHost(); + if (host.equals("0.0.0.0")) { + host = authClient.getHost(); + try { + uri = new URI(uri.getScheme(), uri.getUserInfo(), host, uri.getPort(), uri.getPath(), uri.getQuery(), + uri.getFragment()); + } catch (URISyntaxException e) { + throw new IllegalStateException("Error building URI", e); + } + } + return uri; + } + + protected T doRequest(HttpMethod method, String relativePath, Class retvalClass, Format acceptFormat, + Object sendData, Format sendDataFormat) throws PlatformLayerClientException { + int maxRetries = 1; + for (int i = 1; i <= maxRetries; i++) { + PlatformLayerHttpRequest request = new PlatformLayerHttpRequest(this, method, buildUri(relativePath), + trustKeys); + request.debug = debug; + try { + T retval = null; + if (i == maxRetries) { + retval = request.doRequest(retvalClass, acceptFormat, sendData, sendDataFormat); + } else { + try { + retval = request.doRequest(retvalClass, acceptFormat, sendData, sendDataFormat); + } catch (PlatformLayerAuthenticationException e) { + log.warn("Reauthorizing after auth error", e); + authClient.clearAuthenticationToken(); + } catch (OpenstackClientConnectionException e) { + log.warn("Retrying after connection error", e); + } catch (PlatformLayerClientException e) { + if (HTTP_500_ERROR.equals(e.getHttpResponseCode())) { + log.warn("Retrying after 500 error from Openstack", e); + } else { + log.info("Response code = " + e.getHttpResponseCode()); + throw e; + } + } + + try { + Thread.sleep(SLEEP_BETWEEN_RETRIES); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + if (retval != null) { + if (retval instanceof StreamingResponse) { + // Don't close + request = null; + } + return retval; + } + } finally { + Closeables.closeQuietly(request); + } + } + + throw new IllegalStateException(); // Unreachable, but the compiler doesn't know that + } + + public PrintStream getDebug() { + return debug; + } + + public void setDebug(PrintStream debug) { + this.authClient.setDebug(debug); + this.debug = debug; + } + + public PlatformLayerEndpointInfo getEndpointInfo(ProjectId projectId) { + return new PlatformLayerEndpointInfo(authClient, platformlayerEndpoint, projectId, trustKeys); + } + + public HttpStrategy getHttpStrategy() { + return httpStrategy; + } +} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/ServiceUtils.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/ServiceUtils.java index d76361706..e47888ca9 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/ServiceUtils.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/ServiceUtils.java @@ -2,13 +2,14 @@ import java.util.Collection; -import org.apache.log4j.Logger; import org.platformlayer.core.model.ServiceInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.common.base.Joiner; public class ServiceUtils { - static final Logger log = Logger.getLogger(ServiceUtils.class); + private static final Logger log = LoggerFactory.getLogger(ServiceUtils.class); public static ServiceInfo findByNamespace(Collection services, String namespace) { if (services != null) { diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/StateFilter.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/StateFilter.java index 375ca18bb..265c299c3 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/StateFilter.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/StateFilter.java @@ -1,9 +1,12 @@ package org.platformlayer; +import java.util.Collections; import java.util.EnumSet; +import java.util.List; import org.platformlayer.core.model.ItemBase; import org.platformlayer.core.model.ManagedItemState; +import org.platformlayer.core.model.Tag; public class StateFilter extends Filter { @@ -37,4 +40,22 @@ private static Filter only(EnumSet allowStates) { return new StateFilter(allowStates); } + public static Filter excludeDeleted(Filter filter) { + Filter stateFilter = StateFilter.exclude(ManagedItemState.DELETED); + if (filter == null) { + return stateFilter; + } else { + return Filter.and(filter, stateFilter); + } + } + + @Override + public String toString() { + return "StateFilter [allowStates=" + allowStates + "]"; + } + + @Override + public List getRequiredTags() { + return Collections.emptyList(); + } } diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/StreamingResponse.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/StreamingResponse.java new file mode 100644 index 000000000..ead1fa9c7 --- /dev/null +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/StreamingResponse.java @@ -0,0 +1,30 @@ +package org.platformlayer; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; + +import org.platformlayer.http.HttpResponse; + +import com.google.common.io.Closeables; + +public class StreamingResponse implements Closeable { + + private final InputStream responseStream; + private final HttpResponse response; + + public StreamingResponse(HttpResponse response) throws IOException { + this.response = response; + this.responseStream = response.getInputStream(); + } + + @Override + public void close() throws IOException { + Closeables.closeQuietly(responseStream); + Closeables.closeQuietly(response); + } + + public InputStream getResponseStream() { + return responseStream; + } +} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/TagFilter.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/TagFilter.java index 3a920d6f8..246fa69ce 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/TagFilter.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/TagFilter.java @@ -1,6 +1,10 @@ package org.platformlayer; +import java.util.Arrays; +import java.util.List; + import org.platformlayer.core.model.ItemBase; +import org.platformlayer.core.model.PlatformLayerKey; import org.platformlayer.core.model.Tag; import org.platformlayer.core.model.Tags; @@ -16,8 +20,12 @@ public static Filter byTag(Tag requiredTag) { return filter; } - public static Filter byParent(ItemBase item) { - return byTag(Tag.buildParentTag(item.getKey())); + public static Filter byParent(ItemBase parent) { + return byParent(parent.getKey()); + } + + public static Filter byParent(PlatformLayerKey parentKey) { + return byTag(Tag.buildParentTag(parentKey)); } public boolean matchesTags(Iterable tags) { @@ -26,9 +34,14 @@ public boolean matchesTags(Iterable tags) { } for (Tag tag : tags) { - if (tag.equals(requiredTag)) { - return true; + if (!tag.getKey().equals(requiredTag.getKey())) { + continue; + } + if (!tag.getValue().equals(requiredTag.getValue())) { + continue; } + + return true; } return false; } @@ -43,4 +56,18 @@ public boolean matchesItem(ItemBase item) { return matchesTags(tags); } + public Tag getRequiredTag() { + return requiredTag; + } + + @Override + public String toString() { + return "TagFilter [requiredTag=" + requiredTag + "]"; + } + + @Override + public List getRequiredTags() { + return Arrays.asList(requiredTag); + } + } diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/TypedItemMapper.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/TypedItemMapper.java index 01a295362..d71cbd432 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/TypedItemMapper.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/TypedItemMapper.java @@ -2,17 +2,19 @@ import javax.xml.bind.JAXBException; -import org.openstack.utils.Casts; +import org.platformlayer.common.UntypedItem; import org.platformlayer.ops.OpsException; import org.platformlayer.xml.JaxbHelper; import org.platformlayer.xml.XmlHelper.ElementInfo; import org.w3c.dom.Element; +import com.fathomdb.Casts; +import com.google.common.base.Objects; + public abstract class TypedItemMapper { public T promoteToTyped(UntypedItem untypedItem) throws OpsException { - - ElementInfo elementInfo = untypedItem.getElementInfo(); + ElementInfo elementInfo = ((UntypedItemXml) untypedItem).getRootElementInfo(); Class javaClass = mapToJavaClass(elementInfo); @@ -25,11 +27,24 @@ public T promoteToTyped(UntypedItem untypedItem, Class itemClass) throws JaxbHelper jaxbHelper = JaxbHelper.get(itemClass); T typedItem; try { - Element element = untypedItem.getDataElement(); + Element element = ((UntypedItemXml) untypedItem).getDataElement(); + + String xmlElementName = jaxbHelper.getXmlElementName(); + String nodeName = element.getLocalName(); + if (!Objects.equal(xmlElementName, nodeName)) { + String type = element.getAttribute("xsi:type"); + + if (type != null && type.endsWith(":" + xmlElementName)) { + // OK + } else { + throw new OpsException("Incorrect element type: " + xmlElementName + " vs " + nodeName); + } + } + T object = jaxbHelper.unmarshal(element, itemClass); if (!(object.getClass().isAssignableFrom(itemClass))) { - System.out.println("XML = " + untypedItem.serialize()); + System.out.println("XML = " + ((UntypedItemXml) untypedItem).serialize()); } typedItem = Casts.checkedCast(object, itemClass); diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/TypedManagedItem.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/TypedManagedItem.java deleted file mode 100644 index 337e9e94c..000000000 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/TypedManagedItem.java +++ /dev/null @@ -1,84 +0,0 @@ -//package org.platformlayer; -// -//import org.platformlayer.core.model.ManagedItem; -//import org.platformlayer.core.model.ManagedItemState; -//import org.platformlayer.core.model.Tags; -//import org.platformlayer.ids.ItemType; -//import org.platformlayer.ids.ModelKey; -//import org.platformlayer.ids.ServiceType; -//import org.platformlayer.xml.JaxbHelper; -// -//public class TypedManagedItem { -// ManagedItem item; -// -// ModelKey modelKey; -// -// Class javaClass; -// -// public TypedManagedItem(Class javaClass, ModelKey modelKey, ManagedItem item) { -// this.javaClass = javaClass; -// this.modelKey = modelKey; -// this.item = item; -// } -// -// public T getModel() { -// throw new UnsupportedOperationException(); -// } -// -// public static TypedManagedItem build(Class javaClass, ModelKey modelKey, ManagedItem managedItem) { -// return new TypedManagedItem(javaClass, modelKey, managedItem); -// } -// -// public ManagedItemState getState() { -// return item.getState(); -// } -// -// public Tags getTags() { -// return item.getTags(); -// } -// -// public ManagedItem getSerialized() { -// return item; -// } -// -// public String getKey() { -// return item.getKey(); -// } -// -// public Class getJavaClass() { -// return javaClass; -// } -// -// public String getUrl() { -// ModelKey modelKey = getModelKey(); -// return UrlUtils.toUrl(modelKey); -// } -// -// public JaxbHelper getJaxbHelper() { -// return JaxbHelper.get(getJavaClass()); -// } -// -// public ServiceType getServiceType() { -// return getModelKey().serviceType; -// } -// -// public ItemType getItemType() { -// return getModelKey().itemType; -// } -// -// public void setState(ManagedItemState active) { -// -// } -// -// public ModelKey getModelKey() { -// return modelKey; -// } -// -// public String getModelData() { -// return item.getModelData(); -// } -// -// public void setModelData(String xml) { -// item.modelData = xml; -// } -// } diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/TypedPlatformLayerClient.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/TypedPlatformLayerClient.java index f5244f590..3521f3294 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/TypedPlatformLayerClient.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/TypedPlatformLayerClient.java @@ -1,31 +1,38 @@ package org.platformlayer; import java.util.Collection; +import java.util.Collections; import java.util.List; import javax.inject.Inject; -import org.apache.log4j.Logger; +import org.platformlayer.common.UntypedItem; +import org.platformlayer.common.UntypedItemCollection; +import org.platformlayer.core.model.Action; import org.platformlayer.core.model.ItemBase; -import org.platformlayer.core.model.ManagedItemCollection; -import org.platformlayer.core.model.ManagedItemState; import org.platformlayer.core.model.PlatformLayerKey; import org.platformlayer.core.model.ServiceInfo; import org.platformlayer.core.model.Tag; import org.platformlayer.core.model.TagChanges; import org.platformlayer.core.model.Tags; +import org.platformlayer.ids.ManagedItemId; import org.platformlayer.ids.ProjectId; import org.platformlayer.jobs.model.JobData; +import org.platformlayer.jobs.model.JobDataList; +import org.platformlayer.jobs.model.JobExecutionList; import org.platformlayer.jobs.model.JobLog; +import org.platformlayer.metrics.model.MetricDataStream; import org.platformlayer.metrics.model.MetricInfoCollection; -import org.platformlayer.metrics.model.MetricValues; +import org.platformlayer.metrics.model.MetricQuery; import org.platformlayer.ops.OpsException; import org.platformlayer.xml.JaxbHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.common.collect.Lists; public class TypedPlatformLayerClient implements PlatformLayerClient { - static final Logger log = Logger.getLogger(TypedPlatformLayerClient.class); + private static final Logger log = LoggerFactory.getLogger(TypedPlatformLayerClient.class); final PlatformLayerClient platformLayerClient; final TypedItemMapper mapper; @@ -76,55 +83,47 @@ public T getItem(PlatformLayerKey path) throws OpsException { return item; } + @Override public T findItem(PlatformLayerKey path, Class itemClass) throws OpsException { - UntypedItem cloudItemUntyped = platformLayerClient.getItemUntyped(path); - if (cloudItemUntyped == null) { - return null; - } + return platformLayerClient.findItem(path, itemClass); + } + + public T findItem(String id, Class itemClass) throws OpsException { + PlatformLayerKey key = toKey(itemClass, id); - return promoteToTyped(cloudItemUntyped, itemClass); + return findItem(key, itemClass); } - public T findItem(PlatformLayerKey path) throws OpsException { - UntypedItem cloudItemUntyped = platformLayerClient.getItemUntyped(path); - if (cloudItemUntyped == null) { - return null; - } + public PlatformLayerKey toKey(Class itemClass, String id) throws PlatformLayerClientException { + JaxbHelper jaxbHelper = PlatformLayerClientBase.toJaxbHelper(itemClass, new Class[0]); + ManagedItemId itemId = new ManagedItemId(id); - return promoteToTyped(cloudItemUntyped); + PlatformLayerKey key = PlatformLayerClientBase.toKey(jaxbHelper, itemId, itemClass, + platformLayerClient.listServices(true)); + return key; + } + + @Override + public T findItem(PlatformLayerKey path) throws OpsException { + return platformLayerClient.findItem(path); } /** * If using directly, consider using OwnedItem instead */ + @Override @Deprecated public T putItemByTag(T item, Tag uniqueTag) throws OpsException { - JaxbHelper jaxbHelper = PlatformLayerClientBase.toJaxbHelper(item); - - String xml = PlatformLayerClientBase.serialize(jaxbHelper, item); - PlatformLayerKey key = PlatformLayerClientBase.toKey(jaxbHelper, item, platformLayerClient.listServices(true)); - - UntypedItem ret = platformLayerClient.putItemByTag(key, uniqueTag, xml, Format.XML); - Class itemClass = (Class) item.getClass(); - return promoteToTyped(ret, itemClass); - + return platformLayerClient.putItemByTag(item, uniqueTag); } /** * Consider using putItemByTag instead (or OwnedItem) for idempotency */ + @Override @Deprecated - public T putItem(T item) throws OpsException { - JaxbHelper jaxbHelper = PlatformLayerClientBase.toJaxbHelper(item); - - String xml = PlatformLayerClientBase.serialize(jaxbHelper, item); - - PlatformLayerKey key = PlatformLayerClientBase.toKey(jaxbHelper, item, platformLayerClient.listServices(true)); - - UntypedItem created = platformLayerClient.putItem(key, xml, Format.XML); - - Class itemClass = (Class) item.getClass(); - return promoteToTyped(created, itemClass); + public T putItem(T item) throws OpsException { + return platformLayerClient.putItem(item); } // public Iterable listItems(Class itemClass) throws PlatformLayerClientException { @@ -132,18 +131,22 @@ public T putItem(T item) throws OpsException { // } @Override - public void deleteItem(PlatformLayerKey key) throws PlatformLayerClientException { - platformLayerClient.deleteItem(key); + public JobData deleteItem(PlatformLayerKey key) throws PlatformLayerClientException { + return platformLayerClient.deleteItem(key); } - public Tags addTag(PlatformLayerKey key, Tag tag) throws PlatformLayerClientException { + public Tags addTags(PlatformLayerKey key, List tags) throws PlatformLayerClientException { TagChanges changeTags = new TagChanges(); - changeTags.addTags.add(tag); + changeTags.addTags.addAll(tags); return changeTags(key, changeTags); } + public Tags addTag(PlatformLayerKey key, Tag tag) throws PlatformLayerClientException { + return addTags(key, Collections.singletonList(tag)); + } + public Tags addUniqueTag(PlatformLayerKey key, Tag tag) throws PlatformLayerClientException { // Sometimes we require idempotency; we can do this using unique tags. // TODO: Implement this @@ -155,27 +158,43 @@ public Tags addUniqueTag(PlatformLayerKey key, Tag tag) throws PlatformLayerClie // return platformLayerClient.listItems(itemClass, filter); // } - public List listItems(Class clazz, boolean showDeleted) throws OpsException { - Filter filter = showDeleted ? null : StateFilter.exclude(ManagedItemState.DELETED); + public List listItems(Class clazz, boolean includeDeleted) throws OpsException { + Filter filter = null; + if (!includeDeleted) { + filter = StateFilter.excludeDeleted(filter); + } return listItems(clazz, filter); } + @Override public List listItems(Class clazz) throws OpsException { return listItems(clazz, false); } - public List listItems(Class clazz, Filter filter) throws OpsException { - JaxbHelper jaxbHelper = PlatformLayerClientBase.toJaxbHelper(clazz, ManagedItemCollection.class); - PlatformLayerKey path = PlatformLayerClientBase.toKey(jaxbHelper, null, platformLayerClient.listServices(true)); + public List listItems(Class clazz, PlatformLayerKey parent) throws OpsException { + boolean includeDeleted = false; - Iterable untypedItems = this.platformLayerClient.listItemsUntyped(path); + Filter filter = TagFilter.byParent(parent); + if (!includeDeleted) { + filter = StateFilter.excludeDeleted(filter); + } - List items = Lists.newArrayList(); + return listItems(clazz, filter); + } - for (UntypedItem untypedItem : untypedItems) { - T item = promoteToTyped(untypedItem, clazz); - items.add(item); - } + public List listItems(Class clazz, Filter filter) throws OpsException { + // JaxbHelper jaxbHelper = PlatformLayerClientBase.toJaxbHelper(clazz, ManagedItemCollection.class); + // PlatformLayerKey path = PlatformLayerClientBase.toKey(jaxbHelper, null, + // platformLayerClient.listServices(true)); + // + // List items = Lists.newArrayList(); + // + // for (UntypedItem untypedItem : untypedItems.getItems()) { + // T item = promoteToTyped(untypedItem, clazz); + // items.add(item); + // } + + List items = this.platformLayerClient.listItems(clazz); if (filter != null) { // TODO: Do filtering server-side @@ -191,9 +210,14 @@ public List listItems(Class clazz, Filter filter) throws OpsException } } - @Override public Tags changeTags(PlatformLayerKey key, TagChanges tagChanges) throws PlatformLayerClientException { - return platformLayerClient.changeTags(key, tagChanges); + return changeTags(key, tagChanges, null); + } + + @Override + public Tags changeTags(PlatformLayerKey key, TagChanges tagChanges, Long ifVersion) + throws PlatformLayerClientException { + return platformLayerClient.changeTags(key, tagChanges, ifVersion); } @Override @@ -202,10 +226,15 @@ public ProjectId getProject() { } @Override - public JobData doAction(PlatformLayerKey key, String action) throws PlatformLayerClientException { + public JobData doAction(PlatformLayerKey key, Action action) throws PlatformLayerClientException { return platformLayerClient.doAction(key, action); } + @Override + public JobData doAction(PlatformLayerKey key, String action, Format dataFormat) throws PlatformLayerClientException { + return platformLayerClient.doAction(key, action, dataFormat); + } + /** * Consider using putItemByTag instead (or OwnedItem) for idempotency */ @@ -227,38 +256,53 @@ public UntypedItem putItemByTag(PlatformLayerKey key, Tag uniqueTag, String data } @Override + public UntypedItem getItemUntyped(PlatformLayerKey key, Format format) throws PlatformLayerClientException { + return platformLayerClient.getItemUntyped(key, format); + } + public UntypedItem getItemUntyped(PlatformLayerKey key) throws PlatformLayerClientException { - return platformLayerClient.getItemUntyped(key); + return getItemUntyped(key, Format.XML); } @Override - public Iterable listItemsUntyped(PlatformLayerKey path) throws PlatformLayerClientException { + public Tags getItemTags(PlatformLayerKey key) throws PlatformLayerClientException { + return platformLayerClient.getItemTags(key); + } + + @Override + public UntypedItemCollection listItemsUntyped(PlatformLayerKey path) throws PlatformLayerClientException { return platformLayerClient.listItemsUntyped(path); } @Override - public Iterable listRoots() throws PlatformLayerClientException { + public UntypedItemCollection listRoots() throws PlatformLayerClientException { return platformLayerClient.listRoots(); } @Override - public Iterable listChildren(PlatformLayerKey parent) throws PlatformLayerClientException { - return platformLayerClient.listChildren(parent); + public UntypedItemCollection listChildren(PlatformLayerKey parent, boolean includeDeleted) + throws PlatformLayerClientException { + return platformLayerClient.listChildren(parent, includeDeleted); + } + + @Override + public List listChildrenTyped(PlatformLayerKey parent, boolean includeDeleted) throws OpsException { + return platformLayerClient.listChildrenTyped(parent, includeDeleted); } @Override - public Iterable listJobs() throws PlatformLayerClientException { + public JobDataList listJobs() throws PlatformLayerClientException { return platformLayerClient.listJobs(); } @Override - public JobLog getJobLog(String jobId) throws PlatformLayerClientException { - return platformLayerClient.getJobLog(jobId); + public JobDataList listJobs(PlatformLayerKey target) throws PlatformLayerClientException { + return platformLayerClient.listJobs(target); } @Override - public MetricValues getMetric(PlatformLayerKey key, String metricKey) throws PlatformLayerClientException { - return platformLayerClient.getMetric(key, metricKey); + public MetricDataStream getMetric(MetricQuery query) throws PlatformLayerClientException { + return platformLayerClient.getMetric(query); } @Override @@ -296,4 +340,24 @@ public void ensureLoggedIn() throws PlatformLayerAuthenticationException { platformLayerClient.ensureLoggedIn(); } + @Override + public PlatformLayerEndpointInfo getEndpointInfo(PlatformLayerKey item) { + return platformLayerClient.getEndpointInfo(item); + } + + @Override + public JobLog getJobExecutionLog(String jobId, String executionId) throws PlatformLayerClientException { + return platformLayerClient.getJobExecutionLog(jobId, executionId); + } + + @Override + public JobExecutionList listJobExecutions(String jobId) throws PlatformLayerClientException { + return platformLayerClient.listJobExecutions(jobId); + } + + @Override + public JobExecutionList listJobExecutions() throws PlatformLayerClientException { + return platformLayerClient.listJobExecutions(); + } + } diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/UntypedItem.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/UntypedItem.java deleted file mode 100644 index c50856ed9..000000000 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/UntypedItem.java +++ /dev/null @@ -1,184 +0,0 @@ -package org.platformlayer; - -import javax.xml.bind.JAXBException; -import javax.xml.transform.TransformerException; - -import org.platformlayer.core.model.ManagedItemState; -import org.platformlayer.core.model.PlatformLayerKey; -import org.platformlayer.core.model.Tags; -import org.platformlayer.xml.JaxbHelper; -import org.platformlayer.xml.XmlHelper; -import org.platformlayer.xml.XmlHelper.ElementInfo; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -public class UntypedItem { - - private final Element root; - private Tags tags; - - private PlatformLayerKey platformLayerKey; - - public UntypedItem(Element root) { - this.root = root; - } - - public static UntypedItem build(String xml) { - Element documentElement; - - try { - Document dom = XmlHelper.parseXmlDocument(xml, true); - documentElement = dom.getDocumentElement(); - } catch (Exception e) { - throw new IllegalArgumentException("Error parsing XML", e); - } - - return new UntypedItem(documentElement); - } - - public Element getDataElement() { - return root; - - // String xml = o.getModelData(); - // - // Element documentElement; - // - // try { - // Document dom = XmlHelper.parseXmlDocument(xml, false); - // documentElement = dom.getDocumentElement(); - // } catch (Exception e) { - // throw new IllegalArgumentException("Error parsing XML", e); - // } - } - - // public Object getId() { - // } - // - // public Object getState() { - // } - - public Tags getTags() { - if (tags == null) { - Node tagsElement = XmlHelper.findUniqueChild(root, "tags"); - if (tagsElement == null) { - return null; - } - - JaxbHelper helper = JaxbHelper.get(Tags.class); - try { - tags = (Tags) helper.unmarshal(tagsElement); - } catch (JAXBException e) { - throw new IllegalStateException("Error parsing tags data", e); - } - } - return tags; - } - - // public String getId() { - // Node idElement = findIdElement(); - // if (idElement == null) - // return null; - // return idElement.getTextContent(); - // } - // - // public void setId(String id) { - // Node idElement = findIdElement(); - // if (idElement == null) - // throw new IllegalStateException(); - // idElement.setTextContent(id); - // } - - // private Node findIdElement() { - // Node idElement = XmlHelper.findUniqueChild(root, "id"); - // return idElement; - // } - - private Node findKeyElement(boolean create) { - Node element = XmlHelper.findUniqueChild(root, "key", create); - return element; - } - - public ManagedItemState getState() { - Node element = XmlHelper.findUniqueChild(root, "state"); - if (element == null) { - return null; - } - String state = element.getTextContent(); - return ManagedItemState.valueOf(state); - } - - public String getRootNamespace() { - String namespace = root.getNamespaceURI(); - return namespace; - } - - public String getRootElementName() { - String name = null; - if (name == null) { - // xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns16:networkConnection" - String ns = "http://www.w3.org/2001/XMLSchema-instance"; - String xsiType = root.getAttributeNS(ns, "type"); - if (xsiType != null) { - // String xsiType = xsiTypeNode.getValue(); - String[] tokens = xsiType.split(":"); - if (tokens.length == 1) { - name = tokens[0]; - } else if (tokens.length == 2) { - // namespace = tokens[0]; - name = tokens[1]; - } else { - throw new IllegalStateException(); - } - if (name.isEmpty()) { - name = null; - } - } - } - if (name == null) { - name = root.getLocalName(); - } - // String name = root.getNodeName(); - return name; - } - - public ElementInfo getElementInfo() { - String xmlNamespace = getRootNamespace(); - String rootElement = getRootElementName(); - - return new ElementInfo(xmlNamespace, rootElement); - } - - public String serialize() { - try { - return XmlHelper.toXml(this.root); - } catch (TransformerException e) { - throw new IllegalStateException("Error serializing data", e); - } - } - - public PlatformLayerKey getPlatformLayerKey() { - if (platformLayerKey == null) { - Node element = findKeyElement(false); - if (element != null) { - platformLayerKey = PlatformLayerKey.parse(element.getTextContent()); - } - } - return platformLayerKey; - } - - public void setPlatformLayerKey(PlatformLayerKey platformLayerKey) { - this.platformLayerKey = platformLayerKey; - - Node element = findKeyElement(true); - if (element == null) { - throw new IllegalStateException(); - } - element.setTextContent(platformLayerKey.getUrl()); - // setId(platformLayerKey.getItemId().getKey()); - } - - public Element getRoot() { - return root; - } -} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/UntypedItemCollection.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/UntypedItemCollection.java deleted file mode 100644 index cf17e6ddf..000000000 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/UntypedItemCollection.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.platformlayer; - -import java.util.Iterator; -import java.util.List; - -import org.platformlayer.xml.XmlHelper; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import com.google.common.collect.Lists; - -public class UntypedItemCollection implements Iterable { - final Element root; - final List items; - - public UntypedItemCollection(Element root) { - this.root = root; - - this.items = findItems(); - } - - private List findItems() { - List items = Lists.newArrayList(); - - Node itemsElement = XmlHelper.findUniqueChild(root, "items"); - if (itemsElement != null) { - NodeList childNodes = itemsElement.getChildNodes(); - for (int i = 0; i < childNodes.getLength(); i++) { - Node child = childNodes.item(i); - if (child instanceof Element) { - Element childElement = (Element) child; - // String namespaceURI = childElement.getNamespaceURI(); - String nodeName = childElement.getNodeName(); - if (nodeName.equals("item")) { - UntypedItem untypedItem = new UntypedItem(childElement); - - items.add(untypedItem); - } - } - } - } - return items; - } - - public static UntypedItemCollection build(String xml) { - Element documentElement; - - try { - Document dom = XmlHelper.parseXmlDocument(xml, true); - documentElement = dom.getDocumentElement(); - } catch (Exception e) { - throw new IllegalArgumentException("Error parsing XML", e); - } - - UntypedItemCollection items = new UntypedItemCollection(documentElement); - // for (UntypedItem item : items) { - // PlatformLayerKey platformLayerKey = new PlatformLayerKey(host, project, serviceType, itemType, id); - // item.setPlatformLayerKey(platformLayerKey ); - // } - return items; - } - - @Override - public Iterator iterator() { - return items.iterator(); - } - -} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/UntypedItemJson.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/UntypedItemJson.java new file mode 100644 index 000000000..9dfbbb88a --- /dev/null +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/UntypedItemJson.java @@ -0,0 +1,47 @@ +package org.platformlayer; + +import org.json.JSONObject; +import org.platformlayer.common.UntypedItem; +import org.platformlayer.core.model.ManagedItemState; +import org.platformlayer.core.model.PlatformLayerKey; +import org.platformlayer.core.model.Tags; + +public class UntypedItemJson implements UntypedItem { + private final JSONObject root; + + private UntypedItemJson(JSONObject root) { + this.root = root; + } + + @Override + public PlatformLayerKey getKey() { + throw new UnsupportedOperationException(); + } + + @Override + public Tags getTags() { + throw new UnsupportedOperationException(); + } + + @Override + public ManagedItemState getState() { + throw new UnsupportedOperationException(); + } + + public static UntypedItemJson build(String data) { + JSONObject json; + + try { + json = new JSONObject(data); + } catch (Exception e) { + throw new IllegalArgumentException("Error parsing JSON", e); + } + + return new UntypedItemJson(json); + } + + public JSONObject getRoot() { + return root; + } + +} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/UntypedItemXml.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/UntypedItemXml.java new file mode 100644 index 000000000..046e9f4d5 --- /dev/null +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/UntypedItemXml.java @@ -0,0 +1,342 @@ +package org.platformlayer; + +import javax.xml.bind.JAXBException; + +import org.platformlayer.common.UntypedItem; +import org.platformlayer.core.model.ItemBase; +import org.platformlayer.core.model.Links; +import org.platformlayer.core.model.ManagedItemState; +import org.platformlayer.core.model.PlatformLayerKey; +import org.platformlayer.core.model.Tags; +import org.platformlayer.rest.JaxbXmlCodec; +import org.platformlayer.xml.DomUtils; +import org.platformlayer.xml.JaxbHelper; +import org.platformlayer.xml.XmlHelper; +import org.platformlayer.xml.XmlHelper.ElementInfo; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import com.google.common.base.Strings; + +public class UntypedItemXml implements UntypedItem { + + private final Element root; + private Tags tags; + private Links links; + + private PlatformLayerKey platformLayerKey; + + public UntypedItemXml(Element root) { + this.root = root; + } + + public static UntypedItemXml build(String xml) { + Element documentElement; + + try { + Document dom = XmlHelper.parseXmlDocument(xml, true); + documentElement = dom.getDocumentElement(); + } catch (Exception e) { + throw new IllegalArgumentException("Error parsing XML", e); + } + + return new UntypedItemXml(documentElement); + } + + public Element getDataElement() { + return root; + + // String xml = o.getModelData(); + // + // Element documentElement; + // + // try { + // Document dom = XmlHelper.parseXmlDocument(xml, false); + // documentElement = dom.getDocumentElement(); + // } catch (Exception e) { + // throw new IllegalArgumentException("Error parsing XML", e); + // } + } + + // public Object getId() { + // } + // + // public Object getState() { + // } + + @Override + public Tags getTags() { + if (tags == null) { + Node tagsElement = XmlHelper.findUniqueChild(root, "tags", false); + if (tagsElement == null) { + return null; + } + + try { + tags = JaxbXmlCodec.deserializeXmlObject(tagsElement, Tags.class, false); + } catch (JAXBException e) { + throw new IllegalStateException("Error parsing tags data", e); + } + } + return tags; + } + + public Links getLinks() { + if (links == null) { + Node element = XmlHelper.findUniqueChild(root, "links", false); + if (element == null) { + links = new Links(); + } else { + JaxbHelper helper = JaxbHelper.get(Links.class); + try { + links = (Links) helper.unmarshal(element); + } catch (JAXBException e) { + throw new IllegalStateException("Error parsing tags data", e); + } + } + } + return links; + } + + public void setTags(Tags tags) { + Document document; + + JaxbHelper helper = JaxbHelper.get(Tags.class); + try { + document = helper.marshalToDom(tags); + } catch (JAXBException e) { + throw new IllegalStateException("Error parsing tags data", e); + } + + replaceNode("tags", document.getDocumentElement()); + + // To avoid any possible state problems, we set to null rather than copying + this.tags = null; + } + + public void setLinks(Links links) { + ItemBase item = new ItemBase(); + item.links = links; + + Document document; + + JaxbHelper helper = JaxbHelper.get(ItemBase.class); + try { + document = helper.marshalToDom(item); + } catch (JAXBException e) { + throw new IllegalStateException("Error serializing data", e); + } + + replaceNode("links", XmlHelper.findUniqueChild(document.getDocumentElement(), "links", false)); + + // To avoid any possible state problems, we set to null rather than copying + this.links = null; + } + + private void replaceNode(String key, Node newNode) { + // String xml = XmlHelper.safeToXml(document.getDocumentElement()); + + Node imported = root.getOwnerDocument().adoptNode(newNode); + + Node existing = XmlHelper.findUniqueChild(root, key, false); + if (existing == null) { + root.appendChild(imported); + } else { + root.replaceChild(imported, existing); + } + + // String xml = XmlHelper.safeToXml(root); + } + + // public String getId() { + // Node idElement = findIdElement(); + // if (idElement == null) + // return null; + // return idElement.getTextContent(); + // } + // + // public void setId(String id) { + // Node idElement = findIdElement(); + // if (idElement == null) + // throw new IllegalStateException(); + // idElement.setTextContent(id); + // } + + // private Node findIdElement() { + // Node idElement = XmlHelper.findUniqueChild(root, "id"); + // return idElement; + // } + + private Node findKeyElement(boolean create) { + Node element = XmlHelper.findUniqueChild(root, "key", create); + return element; + } + + @Override + public ManagedItemState getState() { + Node element = XmlHelper.findUniqueChild(root, "state", false); + if (element == null) { + return null; + } + String state = element.getTextContent(); + return ManagedItemState.valueOf(state); + } + + public ElementInfo getRootElementInfo() { + String name = null; + String namespace = null; + + // xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns16:networkConnection" + String xsiNs = "http://www.w3.org/2001/XMLSchema-instance"; + String xsiType = root.getAttributeNS(xsiNs, "type"); + if (xsiType != null) { + // String xsiType = xsiTypeNode.getValue(); + String[] tokens = xsiType.split(":"); + if (tokens.length == 1) { + namespace = null; + name = tokens[0]; + } else if (tokens.length == 2) { + name = tokens[1]; + namespace = mapNamespace(tokens[0]); + } else { + throw new IllegalStateException(); + } + } + + if (Strings.isNullOrEmpty(name)) { + name = root.getLocalName(); + + if (Strings.isNullOrEmpty(name)) { + name = null; + } + } + + if (Strings.isNullOrEmpty(namespace)) { + namespace = root.getNamespaceURI(); + + if (Strings.isNullOrEmpty(namespace)) { + namespace = null; + } + } + + return new ElementInfo(namespace, name); + + } + + private String mapNamespace(String alias) { + String ns = "xmlns"; + Element rootElement = root.getOwnerDocument().getDocumentElement(); + String attributeValue = rootElement.getAttribute(ns + ":" + alias); + if (attributeValue != null) { + return attributeValue; + } else { + throw new IllegalArgumentException(); + } + } + + // public String getRootNamespace() { + // String namespace = null; + // if (namespace == null) { + // // xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns16:networkConnection" + // String ns = "http://www.w3.org/2001/XMLSchema-instance"; + // String xsiType = root.getAttributeNS(ns, "type"); + // if (xsiType != null) { + // // String xsiType = xsiTypeNode.getValue(); + // String[] tokens = xsiType.split(":"); + // if (tokens.length == 1) { + // namespace = null; + // } else if (tokens.length == 2) { + // // namespace = tokens[0]; + // namespace = tokens[0]; + // // name = tokens[1]; + // } else { + // throw new IllegalStateException(); + // } + // if (name.isEmpty()) { + // name = null; + // } + // } + // } + // if (name == null) { + // name = root.getLocalName(); + // } + // // String name = root.getNodeName(); + // return name; + // + // String namespace = root.getNamespaceURI(); + // return namespace; + // } + // + // public String getRootElementName() { + // String name = null; + // if (name == null) { + // // xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns16:networkConnection" + // String ns = "http://www.w3.org/2001/XMLSchema-instance"; + // String xsiType = root.getAttributeNS(ns, "type"); + // if (xsiType != null) { + // // String xsiType = xsiTypeNode.getValue(); + // String[] tokens = xsiType.split(":"); + // if (tokens.length == 1) { + // name = tokens[0]; + // } else if (tokens.length == 2) { + // // namespace = tokens[0]; + // name = tokens[1]; + // } else { + // throw new IllegalStateException(); + // } + // if (name.isEmpty()) { + // name = null; + // } + // } + // } + // if (name == null) { + // name = root.getLocalName(); + // } + // // String name = root.getNodeName(); + // return name; + // } + + // public ElementInfo getElementInfo() { + // String xmlNamespace = getRootNamespace(); + // String rootElement = getRootElementName(); + // + // return new ElementInfo(xmlNamespace, rootElement); + // } + + public String serialize() { + return DomUtils.toXml(this.root); + } + + @Override + public PlatformLayerKey getKey() { + if (platformLayerKey == null) { + Node element = findKeyElement(false); + if (element != null) { + platformLayerKey = PlatformLayerKey.parse(element.getTextContent()); + } + } + return platformLayerKey; + } + + public void setPlatformLayerKey(PlatformLayerKey platformLayerKey) { + this.platformLayerKey = platformLayerKey; + + Node element = findKeyElement(true); + if (element == null) { + throw new IllegalStateException(); + } + element.setTextContent(platformLayerKey.getUrl()); + // setId(platformLayerKey.getItemId().getKey()); + } + + public Element getRoot() { + return root; + } + + @Override + public String toString() { + return getClass().getSimpleName() + ":" + getKey(); + } + +} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/UntypedItemXmlCollection.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/UntypedItemXmlCollection.java new file mode 100644 index 000000000..adf4ca629 --- /dev/null +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/UntypedItemXmlCollection.java @@ -0,0 +1,74 @@ +package org.platformlayer; + +import java.util.Iterator; +import java.util.List; + +import org.platformlayer.common.UntypedItem; +import org.platformlayer.common.UntypedItemCollection; +import org.platformlayer.xml.XmlHelper; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.google.common.collect.Lists; + +public class UntypedItemXmlCollection implements UntypedItemCollection, Iterable { + final Element root; + final List items = Lists.newArrayList(); + + public UntypedItemXmlCollection(Element root) { + this.root = root; + + findItems(); + } + + private void findItems() { + Node itemsElement = XmlHelper.findUniqueChild(root, "items", false); + if (itemsElement != null) { + NodeList childNodes = itemsElement.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node child = childNodes.item(i); + if (child instanceof Element) { + Element childElement = (Element) child; + // String namespaceURI = childElement.getNamespaceURI(); + String nodeName = childElement.getLocalName(); + if (nodeName.equals("item")) { + UntypedItem untypedItem = new UntypedItemXml(childElement); + + items.add(untypedItem); + } + } + } + } + } + + public static UntypedItemXmlCollection build(String xml) { + Element documentElement; + + try { + Document dom = XmlHelper.parseXmlDocument(xml, true); + documentElement = dom.getDocumentElement(); + } catch (Exception e) { + throw new IllegalArgumentException("Error parsing XML", e); + } + + UntypedItemXmlCollection items = new UntypedItemXmlCollection(documentElement); + // for (UntypedItem item : items) { + // PlatformLayerKey platformLayerKey = new PlatformLayerKey(host, project, serviceType, itemType, id); + // item.setPlatformLayerKey(platformLayerKey ); + // } + return items; + } + + @Override + public Iterator iterator() { + return items.iterator(); + } + + @Override + public List getItems() { + return items; + } + +} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/UrlUtils.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/UrlUtils.java deleted file mode 100644 index d63d62121..000000000 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/UrlUtils.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.platformlayer; - -public class UrlUtils { - - // public static String toUrl(ModelKey modelKey) { - // String url = modelKey.getProject().toString() + "/" + modelKey.getServiceType().toString() + "/" + - // modelKey.getItemType().toString(); - // if (modelKey.getItemKey() != null) { - // url += "/" + modelKey.getItemKey().getKey(); - // } - // return url; - // } - -} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/auth/AuthenticationSignature.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/auth/AuthenticationSignature.java index bdb835852..da54652e5 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/auth/AuthenticationSignature.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/auth/AuthenticationSignature.java @@ -8,14 +8,14 @@ import javax.crypto.Mac; import javax.crypto.SecretKey; -import org.openstack.utils.Utf8; import org.platformlayer.crypto.CryptoUtils; +import com.fathomdb.Utf8; import com.google.common.collect.Maps; public class AuthenticationSignature { - public static byte[] calculateSignature(Mac signingKey, String timestamp, String method, String requestPath) { + public static byte[] calculateSignature(Mac mac, String timestamp, String method, String requestPath) { // TODO: Add more parameters to strengthen this? TreeMap signValues = Maps.newTreeMap(); signValues.put("method", method); @@ -38,8 +38,8 @@ public static byte[] calculateSignature(Mac signingKey, String timestamp, String byte[] signature; - synchronized (signingKey) { - signature = CryptoUtils.hmacSha1(signingKey, signData); + synchronized (mac) { + signature = CryptoUtils.computeMac(mac, signData); } return signature; } diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/auth/DirectAuthenticationToken.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/auth/DirectAuthenticationToken.java index b7b55a96d..ffaa80aaf 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/auth/DirectAuthenticationToken.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/auth/DirectAuthenticationToken.java @@ -1,49 +1,47 @@ package org.platformlayer.auth; -import javax.crypto.SecretKey; +import org.platformlayer.http.HttpRequest; -import org.platformlayer.DirectPlatformLayerClient; -import org.platformlayer.crypto.CryptoUtils; -import org.platformlayer.http.SimpleHttpRequest; - -import com.google.common.base.Objects; +import com.fathomdb.crypto.CryptoKey; +import com.fathomdb.crypto.FathomdbCrypto; +import com.fathomdb.utils.Base64; public class DirectAuthenticationToken implements AuthenticationToken { - private final String serviceUrl; - // private final Mac signingKey; - private final String keyId; - private final SecretKey secret; - - public DirectAuthenticationToken(String serviceUrl, String keyId, SecretKey secret) { - this.serviceUrl = serviceUrl; - this.keyId = keyId; + public static final String PREFIX = "project:"; + + private final String token; + private final CryptoKey secret; + + public DirectAuthenticationToken(String token, CryptoKey secret) { + this.token = token; this.secret = secret; + } - // this.signingKey = AuthenticationSignature.buildMac(secret); + // @Override + // public String getServiceUrl(String serviceKey) { + // if (Objects.equal(HttpPlatformLayerClient.SERVICE_PLATFORMLAYER, serviceKey)) { + // return serviceUrl; + // } + // return null; + // } + + public static String encodeToken(int projectId, String projectName) { + String token = PREFIX + projectId + ":" + projectName; + return token; } @Override - public String getServiceUrl(String serviceKey) { - if (Objects.equal(DirectPlatformLayerClient.SERVICE_PLATFORMLAYER, serviceKey)) { - return serviceUrl; - } - return null; + public void populateRequest(HttpRequest httpRequest) { + httpRequest.setRequestHeader("X-Auth-Key", token); + httpRequest.setRequestHeader("X-Auth-Secret", Base64.encode(FathomdbCrypto.serialize(secret))); } - @Override - public void populateRequest(SimpleHttpRequest httpRequest) { - // String method = httpRequest.getMethod(); - // String requestPath = httpRequest.getUrl().getPath(); - // String timestamp = String.valueOf(System.currentTimeMillis()); - // - // byte[] signature = AuthenticationSignature.calculateSignature(signingKey, timestamp, method, requestPath); - // - // httpRequest.setRequestHeader("X-Timestamp", timestamp); - // httpRequest.setRequestHeader("X-Auth-Key", keyId); - // httpRequest.setRequestHeader("X-Auth-Signed", CryptoUtils.toBase64(signature)); - - httpRequest.setRequestHeader("X-Auth-Key", keyId); - httpRequest.setRequestHeader("X-Auth-Secret", CryptoUtils.toBase64(secret.getEncoded())); + public String getToken() { + return token; + } + public CryptoKey getSecret() { + return secret; } + } diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/auth/DirectAuthenticator.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/auth/DirectAuthenticator.java index 163ea09eb..4b4ea4572 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/auth/DirectAuthenticator.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/auth/DirectAuthenticator.java @@ -1,15 +1,16 @@ package org.platformlayer.auth; -public class DirectAuthenticator implements Authenticator { +import java.io.PrintStream; - final AuthenticationToken authenticationToken; +public class DirectAuthenticator implements Authenticator { + final DirectAuthenticationToken authenticationToken; - public DirectAuthenticator(AuthenticationToken authenticationToken) { + public DirectAuthenticator(DirectAuthenticationToken authenticationToken) { this.authenticationToken = authenticationToken; } @Override - public AuthenticationToken getAuthenticationToken() throws OpenstackAuthenticationException { + public DirectAuthenticationToken getAuthenticationToken() { return authenticationToken; } @@ -23,4 +24,9 @@ public String getHost() { throw new UnsupportedOperationException(); } + @Override + public void setDebug(PrintStream debug) { + + } + } diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/auth/PlatformlayerAuthenticator.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/auth/PlatformlayerAuthenticator.java new file mode 100644 index 000000000..e60fc0f5f --- /dev/null +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/auth/PlatformlayerAuthenticator.java @@ -0,0 +1,79 @@ +package org.platformlayer.auth; + +import java.io.PrintStream; +import java.net.URI; +import java.util.List; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.KeyManager; +import javax.net.ssl.TrustManager; + +import org.platformlayer.auth.client.PlatformLayerAuthenticationClient; +import org.platformlayer.auth.v1.AuthenticateResponse; +import org.platformlayer.auth.v1.PasswordCredentials; +import org.platformlayer.http.HttpStrategy; +import org.platformlayer.http.SslConfiguration; +import org.platformlayer.rest.JreRestfulClient; +import org.platformlayer.rest.RestfulClient; + +import com.fathomdb.crypto.ssl.AcceptAllHostnameVerifier; +import com.fathomdb.crypto.ssl.PublicKeyTrustManager; + +public class PlatformlayerAuthenticator implements Authenticator { + final String username; + final String password; + + final PlatformLayerAuthenticationClient client; + + AuthenticationToken token = null; + + public PlatformlayerAuthenticator(HttpStrategy httpStrategy, String username, String password, String baseUrl, + List trustKeys) { + this.username = username; + this.password = password; + + HostnameVerifier hostnameVerifier = null; + KeyManager keyManager = null; + TrustManager trustManager = null; + + if (trustKeys != null) { + trustManager = new PublicKeyTrustManager(trustKeys); + + hostnameVerifier = new AcceptAllHostnameVerifier(); + } + + SslConfiguration sslConfiguration = new SslConfiguration(keyManager, trustManager, hostnameVerifier); + RestfulClient restfulClient = new JreRestfulClient(httpStrategy, baseUrl, sslConfiguration); + this.client = new PlatformLayerAuthenticationClient(restfulClient); + } + + @Override + public AuthenticationToken getAuthenticationToken() throws PlatformlayerAuthenticationClientException { + if (token == null) { + PasswordCredentials passwordCredentials = new PasswordCredentials(); + passwordCredentials.setUsername(username); + passwordCredentials.setPassword(password); + + AuthenticateResponse response = client.authenticate(passwordCredentials); + token = new PlatformlayerAuthenticationToken(response.getAccess()); + } + return token; + } + + @Override + public void clearAuthenticationToken() { + token = null; + } + + @Override + public String getHost() { + URI url = client.getBaseUri(); + return url.getHost(); + } + + @Override + public void setDebug(PrintStream debug) { + client.setDebug(debug); + } + +} diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/FederatedPlatformLayerClient.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/FederatedPlatformLayerClient.java index ea5a8f4a2..a16f28cd6 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/FederatedPlatformLayerClient.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/FederatedPlatformLayerClient.java @@ -1,22 +1,27 @@ package org.platformlayer.federation; -import java.io.InputStream; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; -import org.apache.log4j.Logger; import org.platformlayer.CheckedFunction; import org.platformlayer.Format; import org.platformlayer.PlatformLayerAuthenticationException; import org.platformlayer.PlatformLayerClient; import org.platformlayer.PlatformLayerClientBase; import org.platformlayer.PlatformLayerClientException; +import org.platformlayer.PlatformLayerClientNotFoundException; +import org.platformlayer.PlatformLayerEndpointInfo; import org.platformlayer.TypedItemMapper; import org.platformlayer.TypedPlatformLayerClient; -import org.platformlayer.UntypedItem; +import org.platformlayer.UntypedItemXml; +import org.platformlayer.common.UntypedItem; +import org.platformlayer.common.UntypedItemCollection; +import org.platformlayer.common.UntypedItemCollectionBase; +import org.platformlayer.core.model.Action; import org.platformlayer.core.model.ItemBase; +import org.platformlayer.core.model.ManagedItemCollection; import org.platformlayer.core.model.PlatformLayerKey; import org.platformlayer.core.model.ServiceInfo; import org.platformlayer.core.model.Tag; @@ -32,13 +37,18 @@ import org.platformlayer.ids.ManagedItemId; import org.platformlayer.ids.ProjectId; import org.platformlayer.jobs.model.JobData; +import org.platformlayer.jobs.model.JobDataList; +import org.platformlayer.jobs.model.JobExecutionList; import org.platformlayer.jobs.model.JobLog; +import org.platformlayer.metrics.model.MetricDataStream; import org.platformlayer.metrics.model.MetricInfoCollection; -import org.platformlayer.metrics.model.MetricValues; +import org.platformlayer.metrics.model.MetricQuery; import org.platformlayer.ops.OpsException; import org.platformlayer.service.federation.v1.FederatedService; import org.platformlayer.service.federation.v1.FederatedServiceMap; import org.platformlayer.xml.JaxbHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.common.base.Function; import com.google.common.collect.Iterables; @@ -46,9 +56,9 @@ import com.google.common.collect.Maps; public class FederatedPlatformLayerClient extends PlatformLayerClientBase { - static final Logger log = Logger.getLogger(FederatedPlatformLayerClient.class); + private static final Logger log = LoggerFactory.getLogger(FederatedPlatformLayerClient.class); - // TODO: We could maybe do this with a Dynamic Proxy ?? + // TODO: We could maybe do this with a Dynamic Proxy (i.e. MethodInvocation magic)?? final ForkJoinStrategy forkJoinPool; @@ -56,7 +66,13 @@ public class FederatedPlatformLayerClient extends PlatformLayerClientBase { final FederationMap federationMap; - public FederatedPlatformLayerClient(FederationMap federationMap, ForkJoinStrategy forkJoinPool) { + final ProjectId defaultProject; + + public FederatedPlatformLayerClient(TypedItemMapper mapper, ProjectId defaultProject, FederationMap federationMap, + ForkJoinStrategy forkJoinPool) { + super(mapper); + + this.defaultProject = defaultProject; this.federationMap = federationMap; this.forkJoinPool = forkJoinPool; @@ -77,41 +93,32 @@ public FederatedPlatformLayerClient(FederationMap federationMap, ForkJoinStrateg // return buildUsingProperties(properties); // } - public static FederatedPlatformLayerClient buildUsingConfig(InputStream is, TypedItemMapper mapper) - throws OpsException { - FederationConfiguration federationMapConfig = SmartDeserialization.deserialize(FederationConfiguration.class, - is); - FederationMap federationMap = new FederationMap(mapper, federationMapConfig); - - // int parallelism = Runtime.getRuntime().availableProcessors(); - // // Because we're doing lots of HTTP requests, rather than being CPU bound, we massively increase the - // parallelism - // parallelism *= 256; - - ForkJoinStrategy forkJoinPool = new FakeForkJoinStrategy(); - - return new FederatedPlatformLayerClient(federationMap, forkJoinPool); - } + // public static FederatedPlatformLayerClient buildUsingConfig(InputStream is, TypedItemMapper mapper) + // throws OpsException { + // FederationConfiguration federationMapConfig = SmartDeserialization.deserialize(FederationConfiguration.class, + // is); + // FederationMap federationMap = new FederationMap(mapper, federationMapConfig); + // + // // int parallelism = Runtime.getRuntime().availableProcessors(); + // // // Because we're doing lots of HTTP requests, rather than being CPU bound, we massively increase the + // // parallelism + // // parallelism *= 256; + // + // ForkJoinStrategy forkJoinPool = new FakeForkJoinStrategy(); + // + // return new FederatedPlatformLayerClient(federationMap, forkJoinPool); + // } void buildClients() { // TODO: Fork/Join? - for (FederationMapping key : federationMap.getAllKeys()) { + for (FederationMapping key : federationMap.getAllTargetKeys()) { TypedPlatformLayerClient client = federationMap.buildClient(key); ChildClient child = new ChildClient(key, client); childClients.put(key, child); } - TypedPlatformLayerClient localClient = federationMap.getLocalClient(); - if (localClient != null) { - FederationKey host = FederationKey.LOCAL_FEDERATION_KEY; - ProjectId project = localClient.getProject(); - FederationMapping mapKey = new FederationMapping(host, project); - ChildClient childClient = new ChildClient(mapKey, localClient); - childClients.put(childClient.key, childClient); - } - if (childClients.isEmpty()) { throw new IllegalStateException(); } @@ -130,13 +137,13 @@ public ChildClient(FederationMapping key, TypedPlatformLayerClient client) { } } - public UntypedItem setHost(UntypedItem item) { - // if (!key.equals(FederationKey.LOCAL_FEDERATION_KEY)) { - PlatformLayerKey plk = item.getPlatformLayerKey(); - item.setPlatformLayerKey(changeHost(plk)); - // } - return item; - } + // public UntypedItem setHost(UntypedItemXml item) { + // // if (!key.equals(FederationKey.LOCAL_FEDERATION_KEY)) { + // PlatformLayerKey plk = item.getKey(); + // item.setPlatformLayerKey(changeHost(plk)); + // // } + // return item; + // } public JobData setHost(JobData item) { // if (!key.equals(FederationKey.LOCAL_FEDERATION_KEY)) { @@ -162,13 +169,22 @@ public T setHost(T item) { } itemBase.setKey(changeHost(plk)); // } + } else if (item instanceof UntypedItemXml) { + UntypedItemXml untypedItemXml = (UntypedItemXml) item; + PlatformLayerKey plk = untypedItemXml.getKey(); + untypedItemXml.setPlatformLayerKey(changeHost(plk)); } else { - throw new IllegalStateException(); + throw new UnsupportedOperationException(); } // } return item; } + + @Override + public String toString() { + return "ChildClient [key=" + key + "]"; + } } static class MappedPlatformLayerKey { @@ -191,7 +207,7 @@ static abstract class HostFunction implements CheckedFunction> { + static class ListItemsUntyped extends HostFunction { final PlatformLayerKey path; public ListItemsUntyped(PlatformLayerKey path) { @@ -199,11 +215,49 @@ public ListItemsUntyped(PlatformLayerKey path) { } @Override - public Iterable apply(final ChildClient child) throws PlatformLayerClientException { + public UntypedItemCollection apply(final ChildClient child) throws PlatformLayerClientException { return child.client.listItemsUntyped(path); } } + static class ListItemsTyped extends HostFunction> { + private final Class clazz; + + public ListItemsTyped(Class clazz) { + this.clazz = clazz; + } + + @Override + public List apply(final ChildClient child) throws PlatformLayerClientException { + try { + return child.client.listItems(clazz); + } catch (OpsException e) { + throw new PlatformLayerClientException("Error listing items", e); + } + } + } + + static class ListChildren extends HostFunction { + final PlatformLayerKey parent; + final boolean includeDeleted; + + public ListChildren(PlatformLayerKey parent, boolean includeDeleted) { + super(); + this.parent = parent; + this.includeDeleted = includeDeleted; + } + + @Override + public UntypedItemCollection apply(final ChildClient child) throws PlatformLayerClientException { + try { + return child.client.listChildren(parent, includeDeleted); + } catch (PlatformLayerClientNotFoundException e) { + log.warn("Ignoring not found from federated client on: " + e.getUrl()); + return UntypedItemCollectionBase.empty(); + } + } + } + // static class ListItemsTyped extends HostFunction> { // final Class clazz; // final Filter filter; @@ -231,51 +285,65 @@ public Iterable apply(final ChildClient child) throws PlatformLayer } } - static class ListRoots extends HostFunction> { + static class ListRoots extends HostFunction { @Override - public Iterable apply(final ChildClient child) throws PlatformLayerClientException { + public UntypedItemCollection apply(final ChildClient child) throws PlatformLayerClientException { return child.client.listRoots(); } } - static class ListJobs extends HostFunction> { + static class ListJobs extends HostFunction { + final PlatformLayerKey target; + + public ListJobs(PlatformLayerKey target) { + super(); + this.target = target; + } + @Override - public Iterable apply(final ChildClient child) throws PlatformLayerClientException { - return child.client.listJobs(); + public JobDataList apply(final ChildClient child) throws PlatformLayerClientException { + if (target != null) { + return child.client.listJobs(); + } else { + return child.client.listJobs(target); + } } } - static class AddHostUntyped extends HostFunction> { - final HostFunction> inner; + static class AddHostUntyped extends HostFunction { + final HostFunction inner; - public AddHostUntyped(HostFunction> inner) { + public AddHostUntyped(HostFunction inner) { this.inner = inner; } - public static AddHostUntyped wrap(HostFunction> inner) { + public static AddHostUntyped wrap(HostFunction inner) { return new AddHostUntyped(inner); } @Override - public Iterable apply(final ChildClient child) throws PlatformLayerClientException { - return Iterables.transform(inner.apply(child), new Function() { - @Override - public UntypedItem apply(UntypedItem item) { - child.setHost(item); - return item; - } - }); + public UntypedItemCollection apply(final ChildClient child) throws PlatformLayerClientException { + UntypedItemCollection innerItems = inner.apply(child); + Iterable items = Iterables.transform(innerItems.getItems(), + new Function() { + @Override + public UntypedItem apply(UntypedItem item) { + child.setHost(item); + return item; + } + }); + return new UntypedItemCollectionBase(items); } } static class AddHostTyped extends HostFunction> { - final HostFunction> inner; + final HostFunction> inner; - public AddHostTyped(HostFunction> inner) { + public AddHostTyped(HostFunction> inner) { this.inner = inner; } - public static AddHostTyped wrap(HostFunction> inner) { + public static AddHostTyped wrap(HostFunction> inner) { return new AddHostTyped(inner); } @@ -291,32 +359,46 @@ public T apply(T item) { } } - static class AddHostToJob extends HostFunction> { - final HostFunction> inner; + static class AddHostToJob extends HostFunction { + final HostFunction inner; - public AddHostToJob(HostFunction> inner) { + public AddHostToJob(HostFunction inner) { this.inner = inner; } - public static AddHostToJob wrap(HostFunction> inner) { + public static AddHostToJob wrap(HostFunction inner) { return new AddHostToJob(inner); } @Override - public Iterable apply(final ChildClient child) throws PlatformLayerClientException { - return Iterables.transform(inner.apply(child), new Function() { + public JobDataList apply(final ChildClient child) throws PlatformLayerClientException { + JobDataList ret = JobDataList.create(); + JobDataList innerJobs = inner.apply(child); + Iterable outerJobs = Iterables.transform(innerJobs.getJobs(), new Function() { @Override public JobData apply(JobData item) { child.setHost(item); return item; } }); + + ret.jobs = Lists.newArrayList(outerJobs); + + return ret; } } @Override - public Iterable listItemsUntyped(final PlatformLayerKey path) throws PlatformLayerClientException { - return doListConcatenation(getChildClients(path), AddHostUntyped.wrap(new ListItemsUntyped(path))); + public UntypedItemCollection listItemsUntyped(final PlatformLayerKey path) throws PlatformLayerClientException { + return doListConcatenationUntyped(getChildClients(path), AddHostUntyped.wrap(new ListItemsUntyped(path))); + } + + @Override + public List listItems(final Class clazz) throws PlatformLayerClientException { + JaxbHelper jaxbHelper = PlatformLayerClientBase.toJaxbHelper(clazz, ManagedItemCollection.class); + PlatformLayerKey path = PlatformLayerClientBase.toKey(jaxbHelper, null, listServices(true)); + + return doListConcatenationTyped(getChildClients(path), AddHostTyped.wrap(new ListItemsTyped(clazz))); } private Iterable doListConcatenation(Iterable childClients, HostFunction> function) @@ -328,6 +410,33 @@ private Iterable doListConcatenation(Iterable childClients, } } + private UntypedItemCollection doListConcatenationUntyped(Iterable childClients, + HostFunction function) throws PlatformLayerClientException { + try { + return ListConcatentation.joinListsUntypedItems(forkJoinPool, childClients, function); + } catch (ExecutionException e) { + throw new PlatformLayerClientException("Error while building item list", e); + } + } + + private List doListConcatenationTyped(Iterable childClients, + HostFunction> function) throws PlatformLayerClientException { + try { + return ListConcatentation.joinListsTypedItems(forkJoinPool, childClients, function); + } catch (ExecutionException e) { + throw new PlatformLayerClientException("Error while building item list", e); + } + } + + private JobDataList doListConcatenationJobs(Iterable childClients, HostFunction function) + throws PlatformLayerClientException { + try { + return ListConcatentation.joinListsJobs(forkJoinPool, childClients, function); + } catch (ExecutionException e) { + throw new PlatformLayerClientException("Error while building item list", e); + } + } + // @Override // public T getItem(final Class clazz, final PlatformLayerKey key) throws PlatformLayerClientException { // MappedPlatformLayerKey mapped = mapToChild(key); @@ -360,7 +469,7 @@ private Iterable doListConcatenation(Iterable childClients, public UntypedItem putItem(PlatformLayerKey key, String data, Format format) throws PlatformLayerClientException { MappedPlatformLayerKey mapped = mapToChildForPut(key); - UntypedItem untypedItem = UntypedItem.build(data); + UntypedItemXml untypedItem = UntypedItemXml.build(data); untypedItem.setPlatformLayerKey(mapped.key); UntypedItem item = mapped.child.client.putItem(mapped.key, untypedItem.serialize(), format); @@ -369,50 +478,64 @@ public UntypedItem putItem(PlatformLayerKey key, String data, Format format) thr } @Override - public void deleteItem(PlatformLayerKey key) throws PlatformLayerClientException { + public JobData deleteItem(PlatformLayerKey key) throws PlatformLayerClientException { MappedPlatformLayerKey mapped = mapToChild(key); - mapped.child.client.deleteItem(key); + JobData jobData = mapped.child.client.deleteItem(key); + return mapped.child.setHost(jobData); } @Override - public UntypedItem getItemUntyped(PlatformLayerKey key) throws PlatformLayerClientException { + public UntypedItem getItemUntyped(PlatformLayerKey key, Format format) throws PlatformLayerClientException { MappedPlatformLayerKey mapped = mapToChild(key); UntypedItem item = mapped.child.client.getItemUntyped(key); return mapped.child.setHost(item); } @Override - public Iterable listRoots() throws PlatformLayerClientException { - return doListConcatenation(getChildClients(), AddHostUntyped.wrap(new ListRoots())); + public UntypedItemCollection listRoots() throws PlatformLayerClientException { + return doListConcatenationUntyped(getChildClients(), AddHostUntyped.wrap(new ListRoots())); } @Override - public Iterable listJobs() throws PlatformLayerClientException { - return doListConcatenation(getChildClients(), AddHostToJob.wrap(new ListJobs())); + public JobDataList listJobs() throws PlatformLayerClientException { + return doListConcatenationJobs(getChildClients(), AddHostToJob.wrap(new ListJobs(null))); } @Override - public JobData doAction(PlatformLayerKey key, String action) throws PlatformLayerClientException { - MappedPlatformLayerKey mapped = mapToChild(key); - JobData result = mapped.child.client.doAction(mapped.key, action); - return mapped.child.setHost(result); + public JobDataList listJobs(PlatformLayerKey target) throws PlatformLayerClientException { + return doListConcatenationJobs(getChildClients(), AddHostToJob.wrap(new ListJobs(target))); + } + + @Override + public JobExecutionList listJobExecutions() throws PlatformLayerClientException { + throw new UnsupportedOperationException(); } @Override - public Tags changeTags(PlatformLayerKey key, TagChanges tagChanges) throws PlatformLayerClientException { + public JobData doAction(PlatformLayerKey key, Action action) throws PlatformLayerClientException { MappedPlatformLayerKey mapped = mapToChild(key); - return mapped.child.client.changeTags(mapped.key, tagChanges); + JobData result = mapped.child.client.doAction(mapped.key, action); + return mapped.child.setHost(result); } @Override - public JobLog getJobLog(String jobId) throws PlatformLayerClientException { + public JobData doAction(PlatformLayerKey key, String action, Format dataFormat) throws PlatformLayerClientException { throw new UnsupportedOperationException(); } @Override - public MetricValues getMetric(PlatformLayerKey key, String metricKey) throws PlatformLayerClientException { + public Tags changeTags(PlatformLayerKey key, TagChanges tagChanges, Long ifVersion) + throws PlatformLayerClientException { MappedPlatformLayerKey mapped = mapToChild(key); - return mapped.child.client.getMetric(mapped.key, metricKey); + return mapped.child.client.changeTags(mapped.key, tagChanges, ifVersion); + } + + @Override + public MetricDataStream getMetric(MetricQuery query) throws PlatformLayerClientException { + MappedPlatformLayerKey mapped = mapToChild(query.item); + MetricQuery mappedQuery = query.copy(); + mappedQuery.item = mapped.key; + return mapped.child.client.getMetric(mappedQuery); } @Override @@ -530,12 +653,13 @@ private MappedPlatformLayerKey mapToChild(PlatformLayerKey plk) { FederationKey host = plk.getHost(); if (host == null) { - host = FederationKey.LOCAL_FEDERATION_KEY; + host = FederationKey.LOCAL; } ProjectId project = plk.getProject(); if (project == null) { - project = federationMap.getLocalClient().getProject(); + project = defaultProject; + // project = federationMap.getLocalClient().getProject(); } ChildClient childClient = getClient(new FederationMapping(host, project)); @@ -571,6 +695,7 @@ private Iterable getChildClients(PlatformLayerKey path) { ChildClient child = getClient(key); clients.add(child); } + return clients; } @@ -580,7 +705,7 @@ private ChildClient getClient(FederationMapping key) { } if (key.host == null) { - key = new FederationMapping(FederationKey.LOCAL_FEDERATION_KEY, key.project); + key = new FederationMapping(FederationKey.LOCAL, key.project); } ChildClient child = this.childClients.get(key); @@ -603,35 +728,77 @@ private T oneOrNull(Iterable iterable) throws PlatformLayerClientExceptio return item; } - public static PlatformLayerClient build(TypedPlatformLayerClient localClient, TypedItemMapper mapper) + // public static PlatformLayerClient build(TypedPlatformLayerClient localClient, TypedItemMapper mapper) + // throws OpsException { + // FederationMap federationMap = buildFederationMap(localClient, mapper); + // + // ForkJoinStrategy forkJoinPool = new FakeForkJoinStrategy(); + // + // return new FederatedPlatformLayerClient(federationMap, forkJoinPool); + // } + + public static PlatformLayerClient build(ProjectId defaultProject, FederationMap federationMap) throws OpsException { + ForkJoinStrategy forkJoinPool = new FakeForkJoinStrategy(); + + TypedItemMapper mapper = null; + return new FederatedPlatformLayerClient(mapper, defaultProject, federationMap, forkJoinPool); + } + + // public static FederationMap buildFederationMap(HttpStrategy httpStrategy, TypedPlatformLayerClient localClient, + // TypedItemMapper mapper) throws OpsException { + // FederationConfiguration federationMapConfig = buildFederationConfiguration(localClient); + // + // FederationMap federationMap = new FederationMap(httpStrategy, mapper, federationMapConfig); + // + // if (localClient != null) { + // federationMap.addDefault(localClient); + // } + // + // return federationMap; + // } + + public static FederationConfiguration buildFederationConfiguration(TypedPlatformLayerClient localClient) throws OpsException { FederationConfiguration federationMapConfig = new FederationConfiguration(); - for (FederatedService service : localClient.listItems(FederatedService.class)) { - PlatformLayerConnectionConfiguration config = new PlatformLayerConnectionConfiguration(); - config.key = service.getId(); - config.secret = service.getSecret(); - config.server = service.getServer(); - config.tenant = service.getTenant(); - config.username = service.getUsername(); + String federationNamespace = "http://platformlayer.org/service/federation/v1.0"; + boolean federationEnabled = isServiceEnabled(localClient, federationNamespace); - federationMapConfig.systems.add(config); - } + if (federationEnabled) { + for (FederatedService service : localClient.listItems(FederatedService.class)) { + PlatformLayerConnectionConfiguration config = new PlatformLayerConnectionConfiguration(); + config.key = service.getKey(); + config.secret = service.getSecret(); + config.authenticationEndpoint = service.getServer(); + config.tenant = service.getTenant(); + config.username = service.getUsername(); + config.platformlayerEndpoint = service.getServer(); - for (FederatedServiceMap map : localClient.listItems(FederatedServiceMap.class)) { - FederationRule rule = new FederationRule(); - rule.target = map.getTarget(); - rule.serviceType = map.getServiceType(); + federationMapConfig.systems.add(config); + } - federationMapConfig.rules.add(rule); - } + for (FederatedServiceMap map : localClient.listItems(FederatedServiceMap.class)) { + FederationRule rule = new FederationRule(); + rule.target = map.getTarget(); + rule.serviceType = map.getServiceType(); - ForkJoinStrategy forkJoinPool = new FakeForkJoinStrategy(); + federationMapConfig.rules.add(rule); + } + } - FederationMap federationMap = new FederationMap(mapper, federationMapConfig); - federationMap.setLocalClient(localClient); + return federationMapConfig; + } - return new FederatedPlatformLayerClient(federationMap, forkJoinPool); + private static boolean isServiceEnabled(TypedPlatformLayerClient localClient, String namespace) + throws PlatformLayerClientException { + Collection services = localClient.listServices(true); + boolean found = false; + for (ServiceInfo service : services) { + if (namespace.equals(service.getNamespace())) { + found = true; + } + } + return found; } @Override @@ -639,7 +806,7 @@ public UntypedItem putItemByTag(PlatformLayerKey key, Tag uniqueTag, String data throws PlatformLayerClientException { MappedPlatformLayerKey mapped = mapToChildForPut(key); - UntypedItem post = UntypedItem.build(data); + UntypedItemXml post = UntypedItemXml.build(data); post.setPlatformLayerKey(mapped.key); UntypedItem item = mapped.child.client.putItemByTag(mapped.key, uniqueTag, post.serialize(), format); @@ -647,14 +814,41 @@ public UntypedItem putItemByTag(PlatformLayerKey key, Tag uniqueTag, String data } @Override - public Iterable listChildren(PlatformLayerKey parent) throws PlatformLayerClientException { - // TODO: Implement me! - throw new UnsupportedOperationException(); + public UntypedItemCollection listChildren(PlatformLayerKey parent, boolean includeDeleted) + throws PlatformLayerClientException { + return doListConcatenationUntyped(getChildClients(parent), + AddHostUntyped.wrap(new ListChildren(parent, includeDeleted))); } @Override public ProjectId getProject() { - return federationMap.getLocalClient().getProject(); + return defaultProject; // federationMap.getLocalClient().getProject(); + } + + @Override + public PlatformLayerEndpointInfo getEndpointInfo(PlatformLayerKey plk) { + MappedPlatformLayerKey mapped = mapToChild(plk); + + return mapped.child.client.getEndpointInfo(mapped.key); + + } + + @Override + public JobLog getJobExecutionLog(String jobId, String executionId) throws PlatformLayerClientException { + throw new UnsupportedOperationException(); + } + + @Override + public JobExecutionList listJobExecutions(String jobId) throws PlatformLayerClientException { + throw new UnsupportedOperationException(); + // assert false; // This logic is suspect... + // MappedPlatformLayerKey mapped = mapToChild(jobKey); + // return mapped.child.client.listJobExecutions(jobKey); + } + + @Override + public T putItem(T item) throws OpsException { + throw new UnsupportedOperationException(); } } diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/FederationMap.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/FederationMap.java index a46c2fae3..b88048ed4 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/FederationMap.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/FederationMap.java @@ -3,7 +3,7 @@ import java.util.List; import java.util.Map; -import org.platformlayer.DirectPlatformLayerClient; +import org.platformlayer.HttpPlatformLayerClient; import org.platformlayer.PlatformLayerClient; import org.platformlayer.TypedItemMapper; import org.platformlayer.TypedPlatformLayerClient; @@ -11,10 +11,13 @@ import org.platformlayer.federation.model.FederationConfiguration; import org.platformlayer.federation.model.FederationRule; import org.platformlayer.federation.model.PlatformLayerConnectionConfiguration; +import org.platformlayer.http.HttpStrategy; import org.platformlayer.ids.FederationKey; import org.platformlayer.ids.ProjectId; -import org.platformlayer.ids.ServiceType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.google.common.base.Joiner; import com.google.common.base.Objects; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -23,76 +26,123 @@ * Maps platform layer keys to one or more children. */ public class FederationMap { + private static final Logger log = LoggerFactory.getLogger(FederationMap.class); - // FederationKey privateCloud = new FederationKey("private"); - // FederationKey publicCloud = new FederationKey("public"); - private final FederationConfiguration config; - private final Map allKeys; - private TypedPlatformLayerClient localClient; + private final Map targetMap; private final TypedItemMapper mapper; - FederationMap(TypedItemMapper mapper, FederationConfiguration config) { + final List rules; + + final HttpStrategy httpStrategy; + + static class MappedTarget { + PlatformLayerConnectionConfiguration configuration; + TypedPlatformLayerClient client; + } + + public static class Rule { + public FederationMapping targetKey; + public PlatformLayerKey mappedItems; + } + + public FederationMap(HttpStrategy httpStrategy, TypedItemMapper mapper, FederationConfiguration config) { + this.httpStrategy = httpStrategy; this.mapper = mapper; - this.config = config; - this.allKeys = collectSystems(); + this.rules = Lists.newArrayList(); + + this.targetMap = Maps.newHashMap(); + + buildTargetMap(config); + buildRules(config); + } + + public void addDefault(TypedPlatformLayerClient defaultClient) { + FederationKey host = FederationKey.LOCAL; + ProjectId project = defaultClient.getProject(); + FederationMapping mapKey = new FederationMapping(host, project); + + MappedTarget target = new MappedTarget(); + target.client = defaultClient; + + addMapping(mapKey, target); + } + + public void addMapping(FederationMapping mapKey, TypedPlatformLayerClient localClient) { + MappedTarget target = new MappedTarget(); + target.client = localClient; + + addMapping(mapKey, target); } - // private Collection collectFederationKeys() { - // Set keys = Sets.newHashSet(); - // - // for (FederationRule rule : config.rules) { - // FederationKey key = toKey(rule); - // keys.add(key); - // } - // - // return keys; - // } + private void addMapping(FederationMapping mapKey, MappedTarget target) { + if (targetMap.containsKey(mapKey)) { + throw new IllegalArgumentException("Duplicate key: " + mapKey); + } - private Map collectSystems() { - Map keys = Maps.newHashMap(); + targetMap.put(mapKey, target); + } + private void buildTargetMap(FederationConfiguration config) { for (PlatformLayerConnectionConfiguration child : config.systems) { - FederationKey host = new FederationKey(child.server); + FederationKey host = FederationKey.build(child.authenticationEndpoint); ProjectId project = new ProjectId(child.tenant); FederationMapping key = new FederationMapping(host, project); - if (keys.containsKey(key)) { - throw new IllegalArgumentException("Duplicate key: " + key); - } - keys.put(key, child); - } + MappedTarget target = new MappedTarget(); + target.configuration = child; - return keys; + addMapping(key, target); + } } - private FederationMapping toKey(PlatformLayerKey original, FederationRule rule) { - FederationKey targetHost = original.getHost(); - ProjectId targetProject = original.getProject(); + private void buildRules(FederationConfiguration config) { + for (FederationRule federationRule : config.rules) { + Rule rule = new Rule(); + + rule.mappedItems = PlatformLayerKey.fromServiceAndItem(federationRule.serviceType, null); + + for (PlatformLayerConnectionConfiguration system : config.systems) { + if (Objects.equal(system.key, federationRule.target)) { + if (rule.targetKey != null) { + throw new IllegalStateException(); + } - if (rule.target != null) { - PlatformLayerConnectionConfiguration found = null; - for (PlatformLayerConnectionConfiguration system : this.config.systems) { - if (Objects.equal(system.key, rule.target)) { - found = system; + FederationKey host = FederationKey.build(system.authenticationEndpoint); + ProjectId project = new ProjectId(system.tenant); + rule.targetKey = new FederationMapping(host, project); } } - if (found == null) { - throw new IllegalStateException("Cannot find target: " + rule.target); + if (rule.targetKey == null) { + throw new IllegalStateException(); + } + + addRule(rule); + } + } + + private FederationMapping toKey(PlatformLayerKey original, Rule rule) { + FederationKey targetHost = original.getHost(); + ProjectId targetProject = original.getProject(); + + if (rule.targetKey != null) { + MappedTarget target = targetMap.get(rule.targetKey); + if (target == null) { + throw new IllegalStateException("Cannot find target: " + rule.targetKey); } - targetHost = new FederationKey(found.server); - targetProject = new ProjectId(found.tenant); + targetHost = rule.targetKey.host; + targetProject = rule.targetKey.project; } return new FederationMapping(targetHost, targetProject); } - private FederationMapping buildLocal(PlatformLayerKey original) { + private FederationMapping buildDefault(PlatformLayerKey original) { FederationKey targetHost = original.getHost(); if (targetHost == null) { - targetHost = FederationKey.LOCAL_FEDERATION_KEY; + targetHost = FederationKey.LOCAL; } ProjectId targetProject = original.getProject(); @@ -100,20 +150,26 @@ private FederationMapping buildLocal(PlatformLayerKey original) { return new FederationMapping(targetHost, targetProject); } - public Iterable getAllKeys() { - return allKeys.keySet(); + public Iterable getAllTargetKeys() { + return targetMap.keySet(); } public TypedPlatformLayerClient buildClient(FederationMapping key) { - PlatformLayerConnectionConfiguration config = allKeys.get(key); - if (config == null) { + MappedTarget target = targetMap.get(key); + if (target == null) { throw new IllegalArgumentException("Unknown key: " + key); } - PlatformLayerClient client = DirectPlatformLayerClient.buildUsingConfiguration(config); + if (target.client == null) { + PlatformLayerClient client = HttpPlatformLayerClient.buildUsingConfiguration(httpStrategy, + target.configuration); - TypedPlatformLayerClient typedClient = new TypedPlatformLayerClient(client, mapper); - return typedClient; + TypedPlatformLayerClient typedClient = new TypedPlatformLayerClient(client, mapper); + // TODO: Save client?? + return typedClient; + } else { + return target.client; + } } public List getClients(PlatformLayerKey path) { @@ -123,25 +179,19 @@ public List getClients(PlatformLayerKey path) { List keys = Lists.newArrayList(); - for (FederationRule rule : config.rules) { + for (Rule rule : rules) { if (isMatch(rule, path)) { keys.add(toKey(path, rule)); } } - keys.add(buildLocal(path)); + keys.add(buildDefault(path)); - return keys; + if (keys.size() > 1) { + log.debug("Multiple clients for " + path + ": " + Joiner.on(",").join(keys)); + } - // return keys; - // - // - // ServiceType serviceType = path.getServiceType(); - // if (serviceType.getKey().equals("dns")) { - // return Arrays.asList(publicCloud); - // } - // - // return Arrays.asList(privateCloud); + return keys; } public FederationMapping getClientForCreate(PlatformLayerKey path) { @@ -151,14 +201,14 @@ public FederationMapping getClientForCreate(PlatformLayerKey path) { List keys = Lists.newArrayList(); - for (FederationRule rule : config.rules) { + for (Rule rule : rules) { if (isMatch(rule, path)) { keys.add(toKey(path, rule)); } } if (keys.isEmpty()) { - keys.add(buildLocal(path)); + keys.add(buildDefault(path)); } if (keys.size() == 0) { @@ -172,53 +222,41 @@ public FederationMapping getClientForCreate(PlatformLayerKey path) { return keys.get(0); } - private boolean isMatch(FederationRule rule, PlatformLayerKey path) { - ServiceType serviceType = path.getServiceType(); - if (rule.serviceType != null) { - if (!Objects.equal(rule.serviceType, serviceType.getKey())) { + private boolean isMatch(Rule rule, PlatformLayerKey path) { + if (rule.mappedItems == null) { + throw new IllegalStateException(); + // (Used to return true) + } + + if (rule.mappedItems.getHost() != null) { + throw new IllegalStateException(); + } + + if (rule.mappedItems.getServiceType() != null) { + if (!Objects.equal(rule.mappedItems.getServiceType(), path.getServiceType())) { + return false; + } + } + + if (rule.mappedItems.getItemType() != null) { + if (!Objects.equal(rule.mappedItems.getItemType(), path.getItemType())) { return false; } } - return true; - } - public void setLocalClient(TypedPlatformLayerClient localClient) { - if (this.localClient != null) { + if (rule.mappedItems.getItemId() != null) { throw new IllegalStateException(); } - this.localClient = localClient; - } - - public TypedPlatformLayerClient getLocalClient() { - return localClient; - } - - // public FederationKey mapToClient(PlatformLayerKey key) { - // if (key.getHost() != null) { - // throw new IllegalStateException(); - // } - // - // ServiceType serviceType = key.getServiceType(); - // - // for (FederationRule rule : config.rules) { - // if (isMatch(rule, key)) { - // return toKey(rule); - // } - // } - // - // // We rely on a default rlue - // throw new IllegalStateException(); - // // if (serviceType.getKey().equals("dns")) { - // // return publicCloud; - // // } - // // - // // return privateCloud; - // } - - // public static FederationMap buildUsingProperties(Properties properties) { - // FederationMap map = new FederationMap(properties); - // - // return map; - // } + return true; + } + + public void addRule(Rule rule) { + rules.add(rule); + } + + public boolean isEmpty() { + return rules.isEmpty() && targetMap.isEmpty(); + } + } diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/SmartDeserialization.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/SmartDeserialization.java index da9745868..8349893b0 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/SmartDeserialization.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/SmartDeserialization.java @@ -4,10 +4,12 @@ import java.io.InputStream; import java.io.StringReader; -import org.openstack.utils.Io; +import javax.xml.bind.UnmarshalException; + import org.platformlayer.ops.OpsException; import org.platformlayer.xml.JaxbHelper; -import org.platformlayer.xml.UnmarshalException; + +import com.fathomdb.io.IoUtils; public class SmartDeserialization { @@ -20,7 +22,7 @@ public static T deserialize(Class c, InputStream is) throws OpsException String data; try { - data = Io.readAll(is); + data = IoUtils.readAll(is); } catch (IOException e) { throw new OpsException("Error reading data", e); } diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/model/FederationRule.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/model/FederationRule.java index be6ce8d2b..e06813901 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/model/FederationRule.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/model/FederationRule.java @@ -3,8 +3,10 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; +import org.platformlayer.core.model.PlatformLayerKey; + @XmlAccessorType(XmlAccessType.FIELD) public class FederationRule { - public String target; + public PlatformLayerKey target; public String serviceType; } diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/model/PlatformLayerConnectionConfiguration.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/model/PlatformLayerConnectionConfiguration.java index bb46ac720..80e7d260f 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/model/PlatformLayerConnectionConfiguration.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/federation/model/PlatformLayerConnectionConfiguration.java @@ -1,19 +1,28 @@ package org.platformlayer.federation.model; +import java.util.List; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; +import org.platformlayer.core.model.PlatformLayerKey; + @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class PlatformLayerConnectionConfiguration { - public String key; + public PlatformLayerKey key; public String tenant; - public String server; + public String authenticationEndpoint; public String username; public String secret; + + public String platformlayerEndpoint; + + public List authTrustKeys; + public List platformlayerTrustKeys; } diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/forkjoin/CheckedTask.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/forkjoin/CheckedTask.java deleted file mode 100644 index 7c576b529..000000000 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/forkjoin/CheckedTask.java +++ /dev/null @@ -1,31 +0,0 @@ -//package org.platformlayer.forkjoin; -// -//import java.util.concurrent.ForkJoinTask; -// -//public abstract class CheckedTask extends ForkJoinTask { -// private static final long serialVersionUID = 1L; -// -// V result; -// -// @Override -// public V getRawResult() { -// return result; -// } -// -// @Override -// protected void setRawResult(V value) { -// result = value; -// } -// -// protected abstract V compute() throws Exception; -// -// @Override -// protected boolean exec() { -// try { -// result = compute(); -// } catch (Exception e) { -// completeExceptionally(e); -// } -// return true; -// } -// } diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/forkjoin/ListConcatentation.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/forkjoin/ListConcatentation.java index 181278e38..cf9cab954 100644 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/forkjoin/ListConcatentation.java +++ b/bindings/platformlayer-api/src/main/java/org/platformlayer/forkjoin/ListConcatentation.java @@ -1,8 +1,12 @@ package org.platformlayer.forkjoin; +import java.util.List; import java.util.concurrent.ExecutionException; import org.platformlayer.CheckedFunction; +import org.platformlayer.common.UntypedItemCollection; +import org.platformlayer.common.UntypedItemCollectionBase; +import org.platformlayer.jobs.model.JobDataList; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; @@ -16,4 +20,32 @@ public static Iterable joinLists(ForkJoinStrategy return Lists.newArrayList(Iterables.concat(join)); } + public static UntypedItemCollection joinListsUntypedItems( + ForkJoinStrategy forkJoinPool, Iterable keys, final CheckedFunction map) + throws ExecutionException { + Iterable join = ToIterable.join(forkJoinPool, keys, map); + + return UntypedItemCollectionBase.concat(join); + } + + public static List joinListsTypedItems(ForkJoinStrategy forkJoinPool, + Iterable keys, final CheckedFunction, E> map) throws ExecutionException { + Iterable> join = ToIterable.join(forkJoinPool, keys, map); + + List ret = Lists.newArrayList(); + for (Iterable c : join) { + for (T t : c) { + ret.add(t); + } + } + return ret; + } + + public static JobDataList joinListsJobs(ForkJoinStrategy forkJoinPool, + Iterable keys, final CheckedFunction map) throws ExecutionException { + Iterable join = ToIterable.join(forkJoinPool, keys, map); + + return JobDataList.concat(join); + } + } diff --git a/bindings/platformlayer-api/src/main/java/org/platformlayer/forkjoin/RealForkJoinStrategy.java b/bindings/platformlayer-api/src/main/java/org/platformlayer/forkjoin/RealForkJoinStrategy.java deleted file mode 100644 index f3f434be3..000000000 --- a/bindings/platformlayer-api/src/main/java/org/platformlayer/forkjoin/RealForkJoinStrategy.java +++ /dev/null @@ -1,29 +0,0 @@ -//package org.platformlayer.forkjoin; -// -//import java.util.concurrent.Callable; -//import java.util.concurrent.ForkJoinPool; -//import java.util.concurrent.Future; -// -//public class RealForkJoinStrategy extends ForkJoinStrategy { -// final ForkJoinPool forkJoinPool; -// -// public RealForkJoinStrategy(ForkJoinPool forkJoinPool) { -// super(); -// this.forkJoinPool = forkJoinPool; -// } -// -// @Override -// public Future execute(final Callable callable) { -// CheckedTask task = new CheckedTask() { -// private static final long serialVersionUID = 1L; -// -// @Override -// protected T compute() throws Exception { -// return callable.call(); -// } -// }; -// forkJoinPool.execute(task); -// return task; -// } -// -// } \ No newline at end of file diff --git a/gui/gwt-shared/pom.xml b/gui/gwt-shared/pom.xml deleted file mode 100644 index ecefab8e1..000000000 --- a/gui/gwt-shared/pom.xml +++ /dev/null @@ -1,34 +0,0 @@ - - 4.0.0 - - - org.platformlayer - platformlayer-ui-parent - 1.0-SNAPSHOT - - - gwt-shared - jar - PlatformLayer :: GUI :: Shared - - - - - com.google.gwt - gwt-user - provided - - - com.google.web.bindery - requestfactory-server - - - org.platformlayer - platformlayer-xaas-webapp - - - - - - diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/PlatformLayerShared.gwt.xml b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/PlatformLayerShared.gwt.xml deleted file mode 100644 index 457093613..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/PlatformLayerShared.gwt.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/commons/Accessor.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/commons/Accessor.java deleted file mode 100644 index 12ba292ef..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/commons/Accessor.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.platformlayer.ui.shared.client.commons; - -public abstract class Accessor /* implements Function */{ - - public abstract PropertyType get(T o); - - public abstract void set(T o, PropertyType value); - -} diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/commons/BasicInjector.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/commons/BasicInjector.java deleted file mode 100644 index 03e39af3b..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/commons/BasicInjector.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.platformlayer.ui.shared.client.commons; - -import com.google.web.bindery.event.shared.EventBus; -import com.google.web.bindery.requestfactory.shared.RequestFactory; - -public interface BasicInjector { - EventBus getEventBus(); - - RequestFactory getRequestFactory(); -} diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/commons/HttpRequestTransport.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/commons/HttpRequestTransport.java deleted file mode 100644 index caab7b022..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/commons/HttpRequestTransport.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.platformlayer.ui.shared.client.commons; - -import java.util.Map; - -import com.google.common.collect.Maps; -import com.google.gwt.http.client.RequestBuilder; -import com.google.web.bindery.requestfactory.gwt.client.DefaultRequestTransport; - -public class HttpRequestTransport extends DefaultRequestTransport { - final Map headers = Maps.newHashMap(); - - @Override - protected void configureRequestBuilder(RequestBuilder builder) { - super.configureRequestBuilder(builder); - - for (Map.Entry header : headers.entrySet()) { - builder.setHeader(header.getKey(), header.getValue()); - } - } - - public Map getHeaders() { - return headers; - } -} diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/commons/Injection.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/commons/Injection.java deleted file mode 100644 index c0f712ce4..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/commons/Injection.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.platformlayer.ui.shared.client.commons; - -public class Injection { - private static BasicInjector INJECTOR; - - public static BasicInjector injector() { - return INJECTOR; - } -} diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/commons/TextColumn.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/commons/TextColumn.java deleted file mode 100644 index ef4e40cfb..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/commons/TextColumn.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.platformlayer.ui.shared.client.commons; - -import com.google.gwt.cell.client.TextCell; -import com.google.gwt.user.cellview.client.Column; - -public class TextColumn extends Column { - private final Accessor accessor; - - public static TextColumn build(Accessor accessor) { - return new TextColumn(accessor); - } - - public TextColumn(Accessor accessor) { - super(new TextCell()); - this.accessor = accessor; - } - - @Override - public String getValue(T object) { - V value = accessor.get(object); - if (value == null) { - return null; - } - return value.toString(); - } -} diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/events/EditItemEvent.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/events/EditItemEvent.java deleted file mode 100644 index 1c5af63bd..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/events/EditItemEvent.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.platformlayer.ui.shared.client.events; - -import org.platformlayer.ui.shared.client.model.DomainModel; - -import com.google.gwt.event.shared.EventHandler; -import com.google.gwt.event.shared.GwtEvent; -import com.google.web.bindery.requestfactory.shared.EntityProxy; -import com.google.web.bindery.requestfactory.shared.RequestContext; - -public class EditItemEvent extends GwtEvent { - public static final Type TYPE = new Type(); - - /** - * Handles {@link EditItemEvent}. - */ - public interface Handler extends EventHandler { - void startEdit(DomainModel model, EntityProxy person, RequestContext requestContext); - } - - private final EntityProxy person; - private final RequestContext request; - private final DomainModel model; - - public EditItemEvent(DomainModel model, EntityProxy person) { - this(model, person, null); - } - - public EditItemEvent(DomainModel model, EntityProxy person, RequestContext request) { - this.model = model; - this.person = person; - this.request = request; - } - - @Override - protected void dispatch(Handler handler) { - handler.startEdit(model, person, request); - } - - @Override - public com.google.gwt.event.shared.GwtEvent.Type getAssociatedType() { - return TYPE; - } - - public DomainModel getModel() { - return model; - } -} diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/DataGridPatch.css b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/DataGridPatch.css deleted file mode 100644 index 1f40459d3..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/DataGridPatch.css +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ -/* - * This file is used by SummaryWidget to patch the CSS styles used in DataGrid. - * The style rules defined in this file are appended to the default styles in - * DataGrid's CssResource. If there are conflicts, the styles defined in this - * file take precedence over the defaults because these styles appear after the - * default styles. - */ -.dataGridCell { - cursor: pointer; -} \ No newline at end of file diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/DomainModel.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/DomainModel.java deleted file mode 100644 index ba47298d8..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/DomainModel.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.platformlayer.ui.shared.client.model; - -import java.util.List; - -import org.platformlayer.ui.shared.shared.BaseEntityRequest; - -import com.google.gwt.editor.client.Editor; -import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryEditorDriver; -import com.google.web.bindery.requestfactory.shared.Request; -import com.google.web.bindery.requestfactory.shared.RequestFactory; - -public abstract class DomainModel> { - final Class

proxyClass; - - public DomainModel(Class

proxyClass) { - super(); - this.proxyClass = proxyClass; - } - - // static

DomainHelper

get(Class

proxyClass) { - // throw new UnsupportedOperationException(); - // } - - public abstract Editor

buildEditor(); - - public Request> findAll(RequestFactory requestFactory) { - return context(requestFactory).findAll(); - } - - public Class

getProxyClass() { - return proxyClass; - } - - public abstract Context context(RequestFactory requestFactory); - - public abstract void persist(Context context, P item); - - public abstract RequestFactoryEditorDriver> buildEditorDriver(); -} diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/EditItemActivity.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/EditItemActivity.java deleted file mode 100644 index cd2ab65e0..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/EditItemActivity.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.platformlayer.ui.shared.client.model; - -//package org.platformlayer.ui.web.client.service.dns; -// -//import org.platformlayer.ui.web.client.App; -// -//import com.google.gwt.activity.shared.AbstractActivity; -//import com.google.gwt.place.shared.Place; -//import com.google.gwt.user.client.ui.AcceptsOneWidget; -// -//public class EditItemActivity extends AbstractActivity implements HelloView.Presenter { -// // Name that will be appended to "Hello," -// private String name; -// -// public EditItemActivity(EditItemPlace place) { -// this.name = place.getHelloName(); -// } -// -// /** -// * Invoked by the ActivityManager to start a new Activity -// */ -// @Override -// public void start(AcceptsOneWidget containerWidget, EventBus eventBus) { -// HelloView helloView = clientFactory.getHelloView(); -// helloView.setName(name); -// helloView.setPresenter(this); -// containerWidget.setWidget(helloView.asWidget()); -// } -// -// // /** -// // * Ask user before stopping this activity -// // */ -// // @Override -// // public String mayStop() { -// // return "Please hold on. This activity is stopping."; -// // } -// -// /** -// * Navigate to a new Place in the browser -// */ -// public void goTo(Place place) { -// App.injector.getPlaceController().goTo(place); -// } -// } diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/ItemEditorWorkflow.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/ItemEditorWorkflow.java deleted file mode 100644 index e10db467f..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/ItemEditorWorkflow.java +++ /dev/null @@ -1,184 +0,0 @@ -package org.platformlayer.ui.shared.client.model; - -import java.util.Set; - -import javax.validation.ConstraintViolation; - -import org.platformlayer.ui.shared.client.events.EditItemEvent; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.editor.client.Editor; -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.event.dom.client.KeyCodes; -import com.google.gwt.event.dom.client.KeyUpEvent; -import com.google.gwt.event.dom.client.KeyUpHandler; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.uibinder.client.UiHandler; -import com.google.gwt.user.client.ui.DialogBox; -import com.google.gwt.user.client.ui.HTMLPanel; -import com.google.gwt.user.client.ui.Widget; -import com.google.web.bindery.event.shared.EventBus; -import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryEditorDriver; -import com.google.web.bindery.requestfactory.shared.EntityProxy; -import com.google.web.bindery.requestfactory.shared.EntityProxyId; -import com.google.web.bindery.requestfactory.shared.Receiver; -import com.google.web.bindery.requestfactory.shared.Request; -import com.google.web.bindery.requestfactory.shared.RequestContext; -import com.google.web.bindery.requestfactory.shared.RequestFactory; - -public class ItemEditorWorkflow

{ - interface Binder extends UiBinder { - Binder BINDER = GWT.create(Binder.class); - } - - public static void register(EventBus eventBus, final RequestFactory requestFactory/* , final FavoritesManager manager */) { - eventBus.addHandler(EditItemEvent.TYPE, new EditItemEvent.Handler() { - @Override - public void startEdit(DomainModel model, EntityProxy person, RequestContext requestContext) { - new ItemEditorWorkflow(model, requestFactory, /* manager */person).edit(requestContext); - } - }); - } - - @UiField - HTMLPanel contents; - - @UiField - DialogBox dialog; - - // @UiField - // CheckBox favorite; - - @UiField(provided = true) - Widget editorWidget; - - Editor

editor; - - private RequestFactoryEditorDriver> editorDriver; - // private final FavoritesManager manager; - private P proxy; - - private DomainModel model; - - private final RequestFactory requestFactory; - - private ItemEditorWorkflow(DomainModel model, RequestFactory requestFactory, /* FavoritesManager manager */ - P person) { - this.requestFactory = requestFactory; - // this.manager = manager; - this.proxy = person; - - this.model = model; - // TimeSlotListWidget timeSlotEditor = new TimeSlotListWidget(requestFactory); - // ScheduleEditor scheduleEditor = new ScheduleEditor(timeSlotEditor); - // MentorSelector mentorEditor = new MentorSelector(requestFactory); - this.editor = model.buildEditor(); - this.editorWidget = (Widget) this.editor; - - // new AptCacheServiceEditor(/* mentorEditor, scheduleEditor */); - Binder.BINDER.createAndBindUi(this); - contents.addDomHandler(new KeyUpHandler() { - @Override - public void onKeyUp(KeyUpEvent event) { - if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) { - onCancel(null); - } - } - }, KeyUpEvent.getType()); - // this.favorite.setVisible(false); - } - - /** - * Called by the cancel button when it is clicked. This method will just tear down the UI and clear the state of the - * workflow. - */ - @UiHandler("cancel") - void onCancel(ClickEvent event) { - dialog.hide(); - } - - /** - * Called by the edit dialog's save button. This method will flush the contents of the UI into the PersonProxy that - * is being edited, check for errors, and send the request to the server. - */ - @UiHandler("save") - void onSave(ClickEvent event) { - // Flush the contents of the UI - RequestContext context = editorDriver.flush(); - - // Check for errors - if (editorDriver.hasErrors()) { - dialog.setText("Errors detected locally"); - return; - } - - // Send the request - context.fire(new Receiver() { - @Override - public void onConstraintViolation(Set> errors) { - // Otherwise, show ConstraintViolations in the UI - dialog.setText("Errors detected on the server"); - editorDriver.setConstraintViolations(errors); - } - - @Override - public void onSuccess(Void response) { - // If everything went as planned, just dismiss the dialog box - dialog.hide(); - } - }); - } - - // /** - // * Called by the favorite checkbox when its value has been toggled. - // */ - // @UiHandler("favorite") - // void onValueChanged(ValueChangeEvent event) { - // manager.setFavorite(person.stableId(), favorite.getValue()); - // } - - /** - * Construct and display the UI that will be used to edit the current PersonProxy, using the given RequestContext to - * accumulate the edits. - */ - private void edit(RequestContext requestContext) { - editorDriver = model.buildEditorDriver(); - editorDriver.initialize(requestFactory, editor); - - if (requestContext == null) { - // this.favorite.setVisible(true); - fetchAndEdit(); - return; - } - - editorDriver.edit(proxy, requestContext); - // serviceInfoEditor.focus(); - // favorite.setValue(manager.isFavorite(person), false); - dialog.center(); - } - - private void fetchAndEdit() { - // The request is configured arbitrarily - EntityProxyId

stableId = (EntityProxyId

) proxy.stableId(); - Request

fetchRequest = requestFactory.find(stableId); - - // Add the paths that the EditorDrives computes - fetchRequest.with(editorDriver.getPaths()); - - // We could do more with the request, but we just fire it - fetchRequest.to(new Receiver

() { - @Override - public void onSuccess(P proxy) { - ItemEditorWorkflow.this.proxy = proxy; - // Start the edit process - // ServiceInfoRequest context = requestFactory.serviceInfoRequest(); - // Display the UI - edit(model.context(requestFactory)); - // Configure the method invocation to be sent in the context - // context.persist().using(person); - // The context will be fire()'ed from the onSave() method - } - }).fire(); - } -} diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/ItemEditorWorkflow.ui.xml b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/ItemEditorWorkflow.ui.xml deleted file mode 100644 index 19c12bc55..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/ItemEditorWorkflow.ui.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - .dialog { - background: white; - border: thin solid #AAA; - padding: 5px; - -moz-box-shadow: 10px 10px 5px #888; - -moz-border-radius: 5px; - -webkit-box-shadow: 10px 10px 5px #888; - -webkit-border-radius: 5px; - } - - .floatLeft { - float: left; - } - - - Editing... - - - -


-
- Cancel - Save -
- - - \ No newline at end of file diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/ItemGrid.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/ItemGrid.java deleted file mode 100644 index 454f129f5..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/ItemGrid.java +++ /dev/null @@ -1,216 +0,0 @@ -package org.platformlayer.ui.shared.client.model; - -import java.util.Collections; -import java.util.List; - -import org.platformlayer.ui.shared.client.commons.Injection; -import org.platformlayer.ui.shared.client.events.EditItemEvent; -import org.platformlayer.ui.shared.shared.BaseEntityRequest; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.resources.client.CssResource; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.uibinder.client.UiHandler; -import com.google.gwt.user.cellview.client.DataGrid; -import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy; -import com.google.gwt.user.cellview.client.SimplePager; -import com.google.gwt.user.client.ui.Button; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.DockLayoutPanel; -import com.google.gwt.user.client.ui.RequiresResize; -import com.google.gwt.user.client.ui.Widget; -import com.google.gwt.view.client.Range; -import com.google.gwt.view.client.RangeChangeEvent; -import com.google.gwt.view.client.SelectionChangeEvent; -import com.google.gwt.view.client.SingleSelectionModel; -import com.google.web.bindery.event.shared.EventBus; -import com.google.web.bindery.requestfactory.shared.EntityProxy; -import com.google.web.bindery.requestfactory.shared.EntityProxyChange; -import com.google.web.bindery.requestfactory.shared.EntityProxyId; -import com.google.web.bindery.requestfactory.shared.Receiver; -import com.google.web.bindery.requestfactory.shared.RequestFactory; -import com.google.web.bindery.requestfactory.shared.WriteOperation; - -public abstract class ItemGrid

> extends Composite implements - RequiresResize { - - protected final SingleSelectionModel

selectionModel = new SingleSelectionModel

(); - - interface Binder extends UiBinder { - } - - public interface Style extends CssResource { - } - - public interface TableResources extends DataGrid.Resources { - @Override - @Source(value = { DataGrid.Style.DEFAULT_CSS, "DataGridPatch.css" }) - DataGrid.Style dataGridStyle(); - } - - protected int offsetOf(EntityProxyId

personId) { - List

displayedItems = table.getVisibleItems(); - for (int offset = 0, j = displayedItems.size(); offset < j; offset++) { - if (personId.equals(displayedItems.get(offset).stableId())) { - return offset; - } - } - return -1; - } - - protected void refreshSelection() { - P person = selectionModel.getSelectedObject(); - if (person == null) { - return; - } - // eventBus.fireEvent(new EditPersonEvent(person)); - selectionModel.setSelected(person, false); - } - - @UiField - DockLayoutPanel dock; - - @UiField(provided = true) - SimplePager pager = new SimplePager(); - - @UiField(provided = true) - DataGrid

table; - - @UiField - Button create; - - private final EventBus eventBus; - private int lastFetch; - private final int numRows = 20; - private final RequestFactory requestFactory; - - private final DomainModel model; - - public ItemGrid(DomainModel model) { - this.model = model; - - this.eventBus = Injection.injector().getEventBus(); - this.requestFactory = Injection.injector().getRequestFactory(); - - table = new DataGrid

(numRows, GWT. create(TableResources.class)); - initWidget(GWT. create(Binder.class).createAndBindUi(this)); - - create.setText("New " + model.getClass().toString()); - - addColumns(table); - - // table.addColumn(new ScheduleColumn(), "Schedule"); - table.setRowCount(numRows, false); - table.setSelectionModel(selectionModel); - table.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.DISABLED); - - EntityProxyChange.registerForProxyType(eventBus, model.getProxyClass(), new EntityProxyChange.Handler

() { - @Override - public void onProxyChange(EntityProxyChange

event) { - ItemGrid.this.onPersonChanged(event); - } - }); - - // FilterChangeEvent.register(eventBus, new FilterChangeEvent.Handler() { - // @Override - // public void onFilterChanged(FilterChangeEvent e) { - // filter.set(e.getDay(), e.isSelected()); - // if (!pending) { - // pending = true; - // Scheduler.get().scheduleFinally(new ScheduledCommand() { - // @Override - // public void execute() { - // pending = false; - // fetch(0); - // } - // }); - // } - // } - // }); - - selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() { - @Override - public void onSelectionChange(SelectionChangeEvent event) { - ItemGrid.this.refreshSelection(); - } - }); - - fetch(0); - } - - protected abstract void addColumns(DataGrid

table); - - @UiHandler("create") - void onCreate(ClickEvent event) { - Context context = model.context(requestFactory); - - P item = context.edit(context.create(model.getProxyClass())); - model.persist(context, item); - eventBus.fireEvent(new EditItemEvent(model, item, context)); - } - - void onPersonChanged(EntityProxyChange

event) { - if (WriteOperation.PERSIST.equals(event.getWriteOperation())) { - // Re-fetch if we're already displaying the last page - if (table.isRowCountExact()) { - fetch(lastFetch + 1); - } - } - if (WriteOperation.UPDATE.equals(event.getWriteOperation())) { - EntityProxyId

personId = event.getProxyId(); - - // Is the changing record onscreen? - int displayOffset = offsetOf(personId); - if (displayOffset != -1) { - // Record is onscreen and may differ from our data - requestFactory.find(personId).fire(new Receiver

() { - @Override - public void onSuccess(P person) { - // Re-check offset in case of changes while waiting for data - EntityProxyId

stableId = (EntityProxyId

) person.stableId(); - int offset = offsetOf(stableId); - if (offset != -1) { - table.setRowData(table.getPageStart() + offset, Collections.singletonList(person)); - } - } - }); - } - } - } - - @UiHandler("table") - void onRangeChange(RangeChangeEvent event) { - Range r = event.getNewRange(); - int start = r.getStart(); - - fetch(start); - } - - private void fetch(final int start) { - lastFetch = start; - model.findAll(requestFactory).fire(new Receiver>() { - @Override - public void onSuccess(List

response) { - if (lastFetch != start) { - return; - } - - int responses = response.size(); - table.setRowData(start, response); - pager.setPageStart(start); - if (start == 0 || !table.isRowCountExact()) { - table.setRowCount(start + responses, responses < numRows); - } - } - }); - } - - @Override - public void onResize() { - // TODO: Is this really required?? - dock.onResize(); - } - -} diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/ItemGrid.ui.xml b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/ItemGrid.ui.xml deleted file mode 100644 index 8e2e9dd1a..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/ItemGrid.ui.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - .displayInline { - display: inline; - } - - .table { - width: 100%; - table-layout: fixed; - } - - - - - - - - - - - - New DNS Zone - - - - - - - - - \ No newline at end of file diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/common.css b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/common.css deleted file mode 100644 index 85ce90fa2..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/client/model/common.css +++ /dev/null @@ -1,11 +0,0 @@ -/* Common measurements used in the app. */ -@def fieldWidth 30em; - -.editField { - display: inline; - width: fieldWidth; -} - -.rightAlign { - text-align: right; -} \ No newline at end of file diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/GwtServiceBase.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/GwtServiceBase.java deleted file mode 100644 index 1b73d04f6..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/GwtServiceBase.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.platformlayer.ui.shared.server; - -import java.util.List; - -import javax.inject.Inject; -import javax.inject.Provider; - -import org.platformlayer.Scope; -import org.platformlayer.core.model.ItemBase; -import org.platformlayer.ops.OpsException; -import org.platformlayer.ops.auth.OpsAuthentication; -import org.platformlayer.ui.shared.server.inject.PlatformLayerLiveObjects; -import org.platformlayer.xaas.web.resources.ItemService; - -public abstract class GwtServiceBase { - - @Inject - ItemService itemService; - - @Inject - Provider scopeProvider; - - @Inject - Provider authenticationProvider; - - final Class proxyClass; - - public GwtServiceBase(Class proxyClass) { - super(); - this.proxyClass = proxyClass; - } - - public List findAll() throws OpsException { - OpsAuthentication authentication = authenticationProvider.get(); - - return itemService.findAll(authentication, proxyClass); - } - - public T persist(T managedItem) throws OpsException { - OpsAuthentication authentication = authenticationProvider.get(); - - T created = itemService.createItem(authentication, managedItem); - - PlatformLayerLiveObjects liveObjects = PlatformLayerLiveObjects.get(); - liveObjects.notifyCreated(created, created.getId()); - - return created; - } -} \ No newline at end of file diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/InjectedRequestFactoryServlet.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/InjectedRequestFactoryServlet.java deleted file mode 100644 index 9f14b181a..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/InjectedRequestFactoryServlet.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.platformlayer.ui.shared.server.inject; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import com.google.web.bindery.requestfactory.server.ExceptionHandler; -import com.google.web.bindery.requestfactory.server.RequestFactoryServlet; - -@Singleton -public class InjectedRequestFactoryServlet extends RequestFactoryServlet { - private static final long serialVersionUID = 1L; - - @Inject - protected InjectedRequestFactoryServlet(ExceptionHandler exceptionHandler, - ServiceLayerDecoratorFactory decoratorsFactory) { - super(exceptionHandler, decoratorsFactory.buildServiceLayerDecorators()); - } -} diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/InjectingServiceLayerDecorator.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/InjectingServiceLayerDecorator.java deleted file mode 100644 index c6349743c..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/InjectingServiceLayerDecorator.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.platformlayer.ui.shared.server.inject; - -import javax.inject.Inject; - -import com.google.inject.Injector; -import com.google.web.bindery.requestfactory.server.ServiceLayerDecorator; -import com.google.web.bindery.requestfactory.shared.Locator; -import com.google.web.bindery.requestfactory.shared.ServiceLocator; - -public class InjectingServiceLayerDecorator extends ServiceLayerDecorator { - - @Inject - Injector injector; - - @Override - public > T createLocator(Class clazz) { - return injector.getInstance(clazz); - } - - @Override - public T createServiceLocator(Class clazz) { - return injector.getInstance(clazz); - } - -} diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/InjectingServiceLocator.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/InjectingServiceLocator.java deleted file mode 100644 index 4afd74cfe..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/InjectingServiceLocator.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.platformlayer.ui.shared.server.inject; - -import javax.inject.Inject; - -import com.google.inject.Injector; -import com.google.web.bindery.requestfactory.shared.ServiceLocator; - -public class InjectingServiceLocator implements ServiceLocator { - - @Inject - Injector injector; - - @Override - public Object getInstance(Class clazz) { - return injector.getInstance(clazz); - } - -} diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/PlatformLayerLiveObjects.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/PlatformLayerLiveObjects.java deleted file mode 100644 index 60be14330..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/PlatformLayerLiveObjects.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.platformlayer.ui.shared.server.inject; - -import java.util.Map; - -import org.platformlayer.Scope; - -import com.google.common.collect.Maps; - -public class PlatformLayerLiveObjects { - class ClassInstances { - final Map instances = Maps.newHashMap(); - - public T findInstance(String key) { - return instances.get(key); - } - } - - final Map, ClassInstances> byClass = Maps.newHashMap(); - - ClassInstances getClassInstances(Class clazz) { - ClassInstances classInstances = (ClassInstances) byClass.get(clazz); - if (classInstances == null) { - classInstances = new ClassInstances(); - byClass.put(clazz, classInstances); - } - return classInstances; - } - - T findInContext(Class clazz, String id) { - return getClassInstances(clazz).findInstance(id); - } - - public static PlatformLayerLiveObjects get() { - Scope scope = Scope.get(); - PlatformLayerLiveObjects o = scope.get(PlatformLayerLiveObjects.class); - if (o == null) { - o = new PlatformLayerLiveObjects(); - scope.put(o); - } - return o; - } - - public void notifyCreated(T o, String id) { - ClassInstances classInstances = getClassInstances((Class) o.getClass()); - classInstances.instances.put(id, o); - } - - public void notifyLoaded(T o, String id) { - ClassInstances classInstances = getClassInstances((Class) o.getClass()); - classInstances.instances.put(id, o); - } -} diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/PlatformLayerServiceLayerDecorator.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/PlatformLayerServiceLayerDecorator.java deleted file mode 100644 index f7bbb6ce1..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/PlatformLayerServiceLayerDecorator.java +++ /dev/null @@ -1,312 +0,0 @@ -package org.platformlayer.ui.shared.server.inject; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Type; -import java.util.List; -import java.util.Set; - -import javax.inject.Inject; -import javax.inject.Provider; -import javax.validation.ConstraintViolation; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - -import org.platformlayer.core.model.ItemBase; -import org.platformlayer.ops.OpsException; -import org.platformlayer.ops.auth.OpsAuthentication; -import org.platformlayer.xaas.web.resources.ItemService; - -import com.google.web.bindery.requestfactory.server.ServiceLayerDecorator; -import com.google.web.bindery.requestfactory.shared.BaseProxy; -import com.google.web.bindery.requestfactory.shared.Locator; -import com.google.web.bindery.requestfactory.shared.RequestContext; -import com.google.web.bindery.requestfactory.shared.RequestFactory; -import com.google.web.bindery.requestfactory.shared.ServiceLocator; - -public class PlatformLayerServiceLayerDecorator extends ServiceLayerDecorator { - - @Inject - Provider authenticationProvider; - - @Inject - ItemService itemService; - - @Override - public T createDomainObject(Class clazz) { - // TODO Auto-generated method stub - return super.createDomainObject(clazz); - } - - @Override - public > T createLocator(Class clazz) { - // TODO Auto-generated method stub - return super.createLocator(clazz); - } - - @Override - public Object createServiceInstance(Class requestContext) { - // TODO Auto-generated method stub - return super.createServiceInstance(requestContext); - } - - @Override - public T createServiceLocator(Class clazz) { - // TODO Auto-generated method stub - return super.createServiceLocator(clazz); - } - - @Override - public ClassLoader getDomainClassLoader() { - // TODO Auto-generated method stub - return super.getDomainClassLoader(); - } - - @Override - public Method getGetter(Class domainType, String property) { - // TODO Auto-generated method stub - return super.getGetter(domainType, property); - } - - @Override - public Object getId(Object domainObject) { - // TODO Auto-generated method stub - return super.getId(domainObject); - } - - @Override - public Class getIdType(Class domainType) { - // TODO Auto-generated method stub - return super.getIdType(domainType); - } - - @Override - public Object getProperty(Object domainObject, String property) { - Class domainClass = domainObject.getClass(); - - XmlAccessorType xmlAccessorType = domainClass.getAnnotation(XmlAccessorType.class); - if (xmlAccessorType != null && xmlAccessorType.value() == XmlAccessType.FIELD) { - Field field = null; - try { - field = domainClass.getField(property); - } catch (SecurityException e) { - throw new IllegalStateException("Unexpected error while getting field", e); - } catch (NoSuchFieldException e) { - field = null; - } - if (field != null) { - try { - return field.get(domainObject); - } catch (IllegalAccessException e) { - throw new IllegalStateException("Unexpected error while getting field", e); - } - } - } - - // if (domainObject instanceof ManagedItem) { - // boolean passThrough = property.equals("id") || property.equals("version"); - // if (!passThrough) { - // ManagedItem managedItem = (ManagedItem) domainObject; - // - // Document doc = null; - // - // String xml = managedItem.getModelData(); - // - // if (xml != null && !xml.isEmpty()) { - // try { - // doc = XmlHelper.parseXmlDocument(xml, true); - // } catch (ParserConfigurationException e) { - // throw new IllegalArgumentException("Error parsing data", e); - // } catch (SAXException e) { - // throw new IllegalArgumentException("Error parsing data", e); - // } catch (IOException e) { - // throw new IllegalArgumentException("Error parsing data", e); - // } - // } - // - // if (doc != null) { - // Element element = doc.getElementById(property); - // if (element != null) { - // String value = element.getTextContent(); - // return value; - // } - // } - // - // } - // } - // // TODO Auto-generated method stub - - return super.getProperty(domainObject, property); - } - - @Override - public Type getRequestReturnType(Method contextMethod) { - // TODO Auto-generated method stub - return super.getRequestReturnType(contextMethod); - } - - @Override - public Method getSetter(Class domainType, String property) { - // TODO Auto-generated method stub - return super.getSetter(domainType, property); - } - - @Override - public Object getVersion(Object domainObject) { - // TODO Auto-generated method stub - return super.getVersion(domainObject); - } - - @Override - public Object invoke(Method domainMethod, Object... args) { - // TODO Auto-generated method stub - return super.invoke(domainMethod, args); - } - - @Override - public boolean isLive(Object domainObject) { - if (domainObject instanceof ItemBase) { - Class clazz = (Class) domainObject.getClass(); - try { - return findDomainObject(clazz, ((ItemBase) domainObject).getId()) != null; - } catch (OpsException e) { - throw new IllegalStateException("Error checking for object liveness", e); - } - } - // TODO Auto-generated method stub - return super.isLive(domainObject); - } - - private T findDomainObject(Class clazz, String id) throws OpsException { - OpsAuthentication auth = authenticationProvider.get(); - - PlatformLayerLiveObjects liveObjects = PlatformLayerLiveObjects.get(); - T t = liveObjects.findInContext(clazz, id); - if (t == null) { - // Not in context; may well be in database - t = itemService.findItem(auth, clazz, id); - if (t != null) { - liveObjects.notifyLoaded(t, id); - } - } - return t; - } - - @Override - public T loadDomainObject(Class clazz, Object domainId) { - // TODO Auto-generated method stub - return super.loadDomainObject(clazz, domainId); - } - - @Override - public List loadDomainObjects(List> classes, List domainIds) { - // TODO Auto-generated method stub - return super.loadDomainObjects(classes, domainIds); - } - - @Override - public boolean requiresServiceLocator(Method contextMethod, Method domainMethod) { - // TODO Auto-generated method stub - return super.requiresServiceLocator(contextMethod, domainMethod); - } - - @Override - public Class resolveClass(String typeToken) { - // TODO Auto-generated method stub - return super.resolveClass(typeToken); - } - - @Override - public Class resolveClientType(Class domainClass, Class clientType, boolean required) { - // TODO Auto-generated method stub - return super.resolveClientType(domainClass, clientType, required); - } - - @Override - public Class resolveDomainClass(Class clazz) { - // TODO Auto-generated method stub - return super.resolveDomainClass(clazz); - } - - @Override - public Method resolveDomainMethod(String operation) { - // TODO Auto-generated method stub - return super.resolveDomainMethod(operation); - } - - @Override - public Class> resolveLocator(Class domainType) { - // TODO Auto-generated method stub - return super.resolveLocator(domainType); - } - - @Override - public Class resolveRequestContext(String operation) { - // TODO Auto-generated method stub - return super.resolveRequestContext(operation); - } - - @Override - public Method resolveRequestContextMethod(String operation) { - // TODO Auto-generated method stub - return super.resolveRequestContextMethod(operation); - } - - @Override - public Class resolveRequestFactory(String binaryName) { - // TODO Auto-generated method stub - return super.resolveRequestFactory(binaryName); - } - - @Override - public Class resolveServiceClass(Class requestContextClass) { - // TODO Auto-generated method stub - return super.resolveServiceClass(requestContextClass); - } - - @Override - public Class resolveServiceLocator(Class requestContext) { - // TODO Auto-generated method stub - return super.resolveServiceLocator(requestContext); - } - - @Override - public String resolveTypeToken(Class proxyType) { - // TODO Auto-generated method stub - return super.resolveTypeToken(proxyType); - } - - @Override - public void setProperty(Object domainObject, String property, Class expectedType, Object value) { - Class domainClass = domainObject.getClass(); - - XmlAccessorType xmlAccessorType = domainClass.getAnnotation(XmlAccessorType.class); - if (xmlAccessorType != null && xmlAccessorType.value() == XmlAccessType.FIELD) { - Field field = null; - try { - field = domainClass.getField(property); - } catch (SecurityException e) { - throw new IllegalStateException("Unexpected error while setting field", e); - } catch (NoSuchFieldException e) { - field = null; - } - if (field != null) { - try { - field.set(domainObject, value); - return; - } catch (IllegalAccessException e) { - throw new IllegalStateException("Unexpected error while setting field", e); - } - } - } - - super.setProperty(domainObject, property, expectedType, value); - } - - @Override - public Set> validate(T domainObject) { - // TODO Auto-generated method stub - return super.validate(domainObject); - } - -} diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/ServiceLayerDecoratorFactory.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/ServiceLayerDecoratorFactory.java deleted file mode 100644 index 1fa476d25..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/server/inject/ServiceLayerDecoratorFactory.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.platformlayer.ui.shared.server.inject; - -import java.util.List; - -import javax.inject.Inject; - -import com.google.common.collect.Lists; -import com.google.inject.Injector; -import com.google.web.bindery.requestfactory.server.ServiceLayerDecorator; - -public class ServiceLayerDecoratorFactory { - - List decorators = Lists.newArrayList(); - - public ServiceLayerDecorator[] buildServiceLayerDecorators() { - addDecorators(); - - return decorators.toArray(new ServiceLayerDecorator[decorators.size()]); - } - - @Inject - Injector injector; - - protected void addDecorators() { - addDecorator(InjectingServiceLayerDecorator.class); - } - - protected T addDecorator(Class clazz) { - T instance = injector.getInstance(clazz); - decorators.add(instance); - return instance; - } -} diff --git a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/shared/BaseEntityRequest.java b/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/shared/BaseEntityRequest.java deleted file mode 100644 index dc663655d..000000000 --- a/gui/gwt-shared/src/main/java/org/platformlayer/ui/shared/shared/BaseEntityRequest.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.platformlayer.ui.shared.shared; - -import java.util.List; - -import com.google.web.bindery.requestfactory.shared.Request; -import com.google.web.bindery.requestfactory.shared.RequestContext; -import com.google.web.bindery.requestfactory.shared.SkipInterfaceValidation; - -@SkipInterfaceValidation -public interface BaseEntityRequest extends RequestContext { - Request> findAll(); - - // This doesn't work - I think it's http://code.google.com/p/google-web-toolkit/issues/detail?id=6794 - // Request persist(T proxy); -} diff --git a/gui/pom.xml b/gui/pom.xml deleted file mode 100644 index d13862f74..000000000 --- a/gui/pom.xml +++ /dev/null @@ -1,32 +0,0 @@ - - 4.0.0 - - - org.platformlayer - platformlayer-parent - 1.0-SNAPSHOT - - - platformlayer-ui-parent - PlatformLayer :: UI :: Parent - pom - - - gwt-shared - - - - - - ${basedir}/src/main/resources - - - ${basedir}/src/main/java - - - - - - diff --git a/gui/web-main/configuration.properties b/gui/web-main/configuration.properties deleted file mode 100644 index f3975a2d9..000000000 --- a/gui/web-main/configuration.properties +++ /dev/null @@ -1,4 +0,0 @@ -driverClassName=org.postgresql.Driver -url="jdbc:postgresql://127.0.0.1:5432/conductor -username=conductor -password=conductor-password diff --git a/gui/web-main/pom.xml b/gui/web-main/pom.xml deleted file mode 100644 index 214712382..000000000 --- a/gui/web-main/pom.xml +++ /dev/null @@ -1,320 +0,0 @@ - - 4.0.0 - - - org.platformlayer - platformlayer-ui-parent - 1.0-SNAPSHOT - - - web-main - PlatformLayer :: UI :: Main - war - - - - 2.4.0 - - - 1.6 - 1.6 - - - UTF-8 - UTF-8 - - - - - org.platformlayer - service-apt-cache - ${project.version} - - - - org.platformlayer - service-dns-service - ${project.version} - - - - org.platformlayer - service-dns-resolver - ${project.version} - - - - org.platformlayer - service-openldap - ${project.version} - - - - org.platformlayer - platformlayer-xaas-webapp - - - - org.platformlayer - core-model - - - - - com.google.gwt - gwt-user - ${gwtVersion} - - provided - - - - - - javax.servlet - servlet-api - 2.5 - - - - - - com.google.web.bindery - requestfactory-server - ${gwtVersion} - - - - - - - - javax.validation - validation-api - 1.0.0.GA - sources - - - org.hibernate - hibernate-validator - 4.0.2.GA - - - javax.xml.bind - jaxb-api - - - com.sun.xml.bind - jaxb-impl - - - - - - - org.slf4j - slf4j-log4j12 - 1.6.1 - - - org.slf4j - slf4j-api - 1.6.1 - - - com.google.guava - guava-gwt - - - com.google.gwt.inject - gin - 1.5.0 - - - - - - ${project.build.directory}/${project.build.finalName}/WEB-INF/classes - - - - - org.bsc.maven - maven-processor-plugin - 2.0.5 - - - process - - process - - generate-sources - - - - - com.google.web.bindery - requestfactory-apt - ${gwtVersion} - - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 1.7 - - - add-source - generate-sources - - add-source - - - - ${project.build.directory}/generated-sources/apt - - - - - - - - - org.codehaus.mojo - gwt-maven-plugin - 2.3.0-1 - - - com.google.gwt - gwt-user - ${gwtVersion} - - - com.google.gwt - gwt-dev - ${gwtVersion} - - - com.google.gwt - gwt-servlet - ${gwtVersion} - - - - - - prepare-package - - compile - - - - - - - - PlatformLayerUi.html - - true - org.platformlayer.ui.web.PlatformLayerUi - INFO - - - true - - - - - - maven-resources-plugin - 2.4.2 - - - compile - - copy-resources - - - ${project.build.directory}/${project.build.finalName} - - - src/main/webapp - - - - - - - - - - maven-eclipse-plugin - 2.8 - - true - false - 2.0 - - - com.google.gwt.eclipse.core.gwtProjectValidator - - - - com.google.gwt.eclipse.core.gwtNature - - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.bsc.maven - maven-processor-plugin - [2.0.5,) - - process - - - - - - - - - - - - - - - diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/PlatformLayerUi.gwt.xml b/gui/web-main/src/main/java/org/platformlayer/ui/web/PlatformLayerUi.gwt.xml deleted file mode 100644 index 8fd4df8f5..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/PlatformLayerUi.gwt.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/App.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/App.java deleted file mode 100644 index 842f9364f..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/App.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.platformlayer.ui.web.client; - -import org.platformlayer.ui.shared.client.commons.Injection; - -import com.google.gwt.core.client.GWT; - -public class App { - public static final PlatformLayerInjector injector = GWT.create(PlatformLayerInjector.class); - - static { - Injection.injector = App.injector; - } -} diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/PersonEditorWorkflow.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/PersonEditorWorkflow.java deleted file mode 100644 index 4fd0e31f1..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/PersonEditorWorkflow.java +++ /dev/null @@ -1,188 +0,0 @@ -///* -// * Copyright 2010 Google Inc. -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); you may not -// * use this file except in compliance with the License. You may obtain a copy of -// * the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * 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 org.platformlayer.ui.web.client; -// -//import java.util.Set; -// -//import javax.validation.ConstraintViolation; -// -//import org.platformlayer.ui.web.client.widgets.ServiceInfoEditor; -//import org.platformlayer.ui.web.shared.PlatformLayerRequestFactory; -//import org.platformlayer.ui.web.shared.PlatformLayerRequestFactory.ServiceInfoRequest; -//import org.platformlayer.ui.web.shared.ServiceInfoProxy; -// -//import com.google.gwt.core.client.GWT; -//import com.google.gwt.event.dom.client.ClickEvent; -//import com.google.gwt.event.dom.client.KeyCodes; -//import com.google.gwt.event.dom.client.KeyUpEvent; -//import com.google.gwt.event.dom.client.KeyUpHandler; -//import com.google.gwt.event.shared.EventBus; -//import com.google.gwt.uibinder.client.UiBinder; -//import com.google.gwt.uibinder.client.UiField; -//import com.google.gwt.uibinder.client.UiHandler; -//import com.google.gwt.user.client.ui.CheckBox; -//import com.google.gwt.user.client.ui.DialogBox; -//import com.google.gwt.user.client.ui.HTMLPanel; -//import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryEditorDriver; -//import com.google.web.bindery.requestfactory.shared.Receiver; -//import com.google.web.bindery.requestfactory.shared.Request; -//import com.google.web.bindery.requestfactory.shared.RequestContext; -// -///** -// * This class shows how the UI for editing a person is wired up to the RequestFactoryEditorDelegate. It is also responsible for showing and dismissing the PersonEditor. The use of the FavoriteManager -// * shows integration between a remote service and a local service. -// */ -//public class PersonEditorWorkflow { -// interface Binder extends UiBinder { -// Binder BINDER = GWT.create(Binder.class); -// } -// -// interface Driver extends RequestFactoryEditorDriver { -// } -// -// static void register(EventBus eventBus, final PlatformLayerRequestFactory requestFactory/* , final FavoritesManager manager */) { -// // eventBus.addHandler(EditPersonEvent.TYPE, new EditPersonEvent.Handler() { -// // public void startEdit(PersonProxy person, RequestContext requestContext) { -// // new PersonEditorWorkflow(requestFactory, manager, person).edit(requestContext); -// // } -// // }); -// } -// -// @UiField -// HTMLPanel contents; -// -// @UiField -// DialogBox dialog; -// -// @UiField -// CheckBox favorite; -// -// @UiField(provided = true) -// ServiceInfoEditor serviceInfoEditor; -// -// private Driver editorDriver; -// // private final FavoritesManager manager; -// private ServiceInfoProxy person; -// private final PlatformLayerRequestFactory requestFactory; -// -// private PersonEditorWorkflow(PlatformLayerRequestFactory requestFactory/* , FavoritesManager manager */, ServiceInfoProxy person) { -// this.requestFactory = requestFactory; -// // this.manager = manager; -// this.person = person; -// // TimeSlotListWidget timeSlotEditor = new TimeSlotListWidget(requestFactory); -// // ScheduleEditor scheduleEditor = new ScheduleEditor(timeSlotEditor); -// // MentorSelector mentorEditor = new MentorSelector(requestFactory); -// serviceInfoEditor = new ServiceInfoEditor(/* mentorEditor, scheduleEditor */); -// Binder.BINDER.createAndBindUi(this); -// contents.addDomHandler(new KeyUpHandler() { -// public void onKeyUp(KeyUpEvent event) { -// if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) { -// onCancel(null); -// } -// } -// }, KeyUpEvent.getType()); -// this.favorite.setVisible(false); -// } -// -// /** -// * Called by the cancel button when it is clicked. This method will just tear down the UI and clear the state of the workflow. -// */ -// @UiHandler("cancel") -// void onCancel(ClickEvent event) { -// dialog.hide(); -// } -// -// /** -// * Called by the edit dialog's save button. This method will flush the contents of the UI into the PersonProxy that is being edited, check for errors, and send the request to the server. -// */ -// @UiHandler("save") -// void onSave(ClickEvent event) { -// // Flush the contents of the UI -// RequestContext context = editorDriver.flush(); -// -// // Check for errors -// if (editorDriver.hasErrors()) { -// dialog.setText("Errors detected locally"); -// return; -// } -// -// // Send the request -// context.fire(new Receiver() { -// @Override -// public void onConstraintViolation(Set> errors) { -// // Otherwise, show ConstraintViolations in the UI -// dialog.setText("Errors detected on the server"); -// editorDriver.setConstraintViolations(errors); -// } -// -// @Override -// public void onSuccess(Void response) { -// // If everything went as planned, just dismiss the dialog box -// dialog.hide(); -// } -// }); -// } -// -// // /** -// // * Called by the favorite checkbox when its value has been toggled. -// // */ -// // @UiHandler("favorite") -// // void onValueChanged(ValueChangeEvent event) { -// // manager.setFavorite(person.stableId(), favorite.getValue()); -// // } -// -// /** -// * Construct and display the UI that will be used to edit the current PersonProxy, using the given RequestContext to accumulate the edits. -// */ -// private void edit(RequestContext requestContext) { -// editorDriver = GWT.create(Driver.class); -// editorDriver.initialize(requestFactory, serviceInfoEditor); -// -// if (requestContext == null) { -// this.favorite.setVisible(true); -// fetchAndEdit(); -// return; -// } -// -// editorDriver.edit(person, requestContext); -// serviceInfoEditor.focus(); -// // favorite.setValue(manager.isFavorite(person), false); -// dialog.center(); -// } -// -// private void fetchAndEdit() { -// // The request is configured arbitrarily -// Request fetchRequest = requestFactory.find(person.stableId()); -// -// // Add the paths that the EditorDrives computes -// fetchRequest.with(editorDriver.getPaths()); -// -// // We could do more with the request, but we just fire it -// fetchRequest.to(new Receiver() { -// @Override -// public void onSuccess(ServiceInfoProxy person) { -// PersonEditorWorkflow.this.person = person; -// // Start the edit process -// ServiceInfoRequest context = requestFactory.serviceInfoRequest(); -// // Display the UI -// edit(context); -// // Configure the method invocation to be sent in the context -// // context.persist().using(person); -// // The context will be fire()'ed from the onSave() method -// } -// }).fire(); -// } -// } diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/PlatformLayerInjector.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/PlatformLayerInjector.java deleted file mode 100644 index e403bbae4..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/PlatformLayerInjector.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.platformlayer.ui.web.client; - -import java.util.Map; - -import org.platformlayer.ui.shared.client.commons.BasicInjector; -import org.platformlayer.ui.shared.client.commons.HttpRequestTransport; -import org.platformlayer.ui.web.client.PlatformLayerInjector.PlatformLayerBindings; -import org.platformlayer.ui.web.client.widgets.MainPanel; -import org.platformlayer.ui.web.shared.PlatformLayerRequestFactory; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.inject.client.AbstractGinModule; -import com.google.gwt.inject.client.GinModules; -import com.google.gwt.inject.client.Ginjector; -import com.google.inject.Provides; -import com.google.inject.Singleton; -import com.google.web.bindery.event.shared.EventBus; -import com.google.web.bindery.event.shared.SimpleEventBus; - -@GinModules({ PlatformLayerBindings.class }) -public interface PlatformLayerInjector extends Ginjector, BasicInjector { - MainPanel getMainPanel(); - - PlatformLayerRequestFactory getRequestFactory(); - - public class PlatformLayerBindings extends AbstractGinModule { - @Override - protected void configure() { - bind(MainPanel.class).in(Singleton.class); - bind(EventBus.class).to(SimpleEventBus.class).in(Singleton.class); - } - - @Provides - @Singleton - public PlatformLayerRequestFactory createRequestFactory(EventBus eventBus) { - PlatformLayerRequestFactory requests = GWT.create(PlatformLayerRequestFactory.class); - - String baseUrl = GWT.getModuleBaseURL(); - baseUrl = baseUrl.replace("/static/platformlayerui/", "/"); - - String url = baseUrl + "gwtRequest"; - - HttpRequestTransport transport = new HttpRequestTransport(); - transport.setRequestUrl(url); - - Map headers = transport.getHeaders(); - headers.put("X-Auth-Token", "DEV-TOKEN-fathomdb"); - - requests.initialize(eventBus, transport); - - return requests; - } - } - -} diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/PlatformLayerUi.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/PlatformLayerUi.java deleted file mode 100644 index f2de31055..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/PlatformLayerUi.java +++ /dev/null @@ -1,105 +0,0 @@ -package org.platformlayer.ui.web.client; - -import java.util.ArrayList; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.platformlayer.ui.shared.client.model.ItemEditorWorkflow; -import org.platformlayer.ui.web.client.commons.ErrorDialog; -import org.platformlayer.ui.web.client.widgets.MainPanel; -import org.platformlayer.ui.web.shared.PlatformLayerRequestFactory; - -import com.google.gwt.core.client.EntryPoint; -import com.google.gwt.core.client.GWT; -import com.google.gwt.core.client.GWT.UncaughtExceptionHandler; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.user.client.ui.RootLayoutPanel; -import com.google.gwt.user.client.ui.Widget; -import com.google.web.bindery.event.shared.EventBus; -import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryLogHandler; -import com.google.web.bindery.requestfactory.shared.LoggingRequest; - -/** - * The entry point class which performs the initial loading of the DynaTableRf application. - */ -public class PlatformLayerUi implements EntryPoint { - interface Binder extends UiBinder { - } - - private static final Logger log = Logger.getLogger(PlatformLayerUi.class.getName()); - - // @UiField(provided = true) - // SummaryWidget calendar; - - // @UiField(provided = true) - // AptCacheServiceGrid aptCacheServiceGrid; - - // EventBus eventBus = new SimpleEventBus(); - - // @UiField(provided = true) - // FavoritesWidget favorites; - // - // @UiField(provided = true) - // DayFilterWidget filter; - - /** - * This method sets up the top-level services used by the application. - */ - public void onModuleLoad() { - GWT.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { - public void onUncaughtException(Throwable e) { - log.log(Level.SEVERE, e.getMessage(), e); - } - }); - - // final PlatformLayerRequestFactory requests = GWT.create(PlatformLayerRequestFactory.class); - - // String baseUrl = GWT.getModuleBaseURL(); - // baseUrl = baseUrl.replace("/static/platformlayerui/", "/"); - // - // String url = baseUrl + "gwtRequest"; - // - // HttpRequestTransport transport = new HttpRequestTransport(); - // transport.setRequestUrl(url); - // - // Map headers = transport.getHeaders(); - // headers.put("X-Auth-Token", "DEV-TOKEN-fathomdb"); - // - // requests.initialize(eventBus, transport); - - final PlatformLayerRequestFactory requests = App.injector.getRequestFactory(); - - // Add remote logging handler - RequestFactoryLogHandler.LoggingRequestProvider provider = new RequestFactoryLogHandler.LoggingRequestProvider() { - public LoggingRequest getLoggingRequest() { - return requests.loggingRequest(); - } - }; - Logger.getLogger("").addHandler(new ErrorDialog().getHandler()); - Logger.getLogger("").addHandler(new RequestFactoryLogHandler(provider, Level.WARNING, new ArrayList())); - // FavoritesManager manager = new FavoritesManager(requests); - // PersonEditorWorkflow.register(eventBus, requests, manager); - - EventBus eventBus = App.injector.getEventBus(); - - // AptCacheServiceEditorWorkflow.register(eventBus, requests); - ItemEditorWorkflow.register(eventBus, requests); - // calendar = new SummaryWidget(eventBus, requests, 15); - // // favorites = new FavoritesWidget(eventBus, requests, manager); - // // filter = new DayFilterWidget(eventBus); - // - // // TODO: Use Guice/Gin to avoid provided = true - // aptCacheServiceGrid = new AptCacheServiceGrid(eventBus, requests, 15); - - MainPanel mainPanel = App.injector.getMainPanel(); - RootLayoutPanel.get().add(mainPanel); - // - // RootLayoutPanel.get().add(GWT. create(Binder.class).createAndBindUi(this)); - - // Fast test to see if the sample is not being run from devmode - if (GWT.getHostPageBaseURL().startsWith("file:")) { - log.log(Level.SEVERE, "The DynaTableRf sample cannot be run without its" + " server component. If you are running the sample from a" - + " GWT distribution, use the 'ant devmode' target to launch" + " the DTRF server."); - } - } -} diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/PlatformLayerUi.ui.xml b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/PlatformLayerUi.ui.xml deleted file mode 100644 index b01c5080b..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/PlatformLayerUi.ui.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - body { - background-color: white; - color: black; - font-family: Arial, sans-serif; - font-size: small; - margin: 8px; - margin-top: 3px; - } - - .boxed { - border: thin solid black; - margin: 2px; - overflow: hidden; - padding: 5px; - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - } - - .header { - font-weight: bold; - font-size: 200%; - } - - .main { - margin: 5px; - } - - @external gwt-SplitLayoutPanel-VDragger; - .gwt-SplitLayoutPanel-VDragger { - cursor: row-resize; - } - - - - PlatformLayer - - - - - - - - - - \ No newline at end of file diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/commons/ErrorDialog.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/commons/ErrorDialog.java deleted file mode 100644 index 17625bafa..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/commons/ErrorDialog.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2010 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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 org.platformlayer.ui.web.client.commons; - -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.LogRecord; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.uibinder.client.UiHandler; -import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.ui.DialogBox; -import com.google.gwt.user.client.ui.TextArea; - -/** - * A simple glasspanel popup that terminates interaction with the application. - */ -public class ErrorDialog { - interface Binder extends UiBinder { - } - - @UiField - DialogBox errorDialog; - - @UiField - TextArea errorMessage; - - public ErrorDialog() { - GWT. create(Binder.class).createAndBindUi(this); - } - - /** - * @return - */ - public Handler getHandler() { - return new Handler() { - { - setLevel(Level.SEVERE); - } - - @Override - public void close() { - } - - @Override - public void flush() { - } - - @Override - public void publish(LogRecord record) { - if (isLoggable(record)) { - errorMessage.setText(record.getMessage()); - errorDialog.center(); - } - } - }; - } - - @UiHandler("dismiss") - void onDismiss(ClickEvent event) { - errorDialog.hide(); - } - - @UiHandler("reload") - void onReload(ClickEvent event) { - Window.Location.reload(); - } -} \ No newline at end of file diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/commons/ErrorDialog.ui.xml b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/commons/ErrorDialog.ui.xml deleted file mode 100644 index 5ca904c44..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/commons/ErrorDialog.ui.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - .dialog { - background: white; - border: thin solid black; - margin: 2px; - overflow: hidden; - padding: 5px; - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - } - - .glass { - filter: literal('alpha(opacity = 75)'); - opacity: 0.75; - background-color: #000000; - } - - .message { - height: 400px; - width: 400px; - } - - - - An unexpected application error has occurred -
- You may wish to reload the application -
- - -
- Continue - Reload -
-
-
\ No newline at end of file diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/places/AppActivityMapper.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/places/AppActivityMapper.java deleted file mode 100644 index a8d875a80..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/places/AppActivityMapper.java +++ /dev/null @@ -1,22 +0,0 @@ -//package org.platformlayer.ui.web.client.places; -// -//import org.platformlayer.ui.web.client.service.dns.EditItemActivity; -// -//import com.google.gwt.activity.shared.Activity; -//import com.google.gwt.activity.shared.ActivityMapper; -//import com.google.gwt.place.shared.Place; -// -//public class AppActivityMapper implements ActivityMapper { -// -// public AppActivityMapper() { -// } -// -// @Override -// public Activity getActivity(Place place) { -// if (place instanceof EditItemPlace) -// return new EditItemActivity((EditItemPlace) place); -// // else if (place instanceof GoodbyePlace) -// // return new GoodbyeActivity((GoodbyePlace) place, clientFactory); -// return null; -// } -// } \ No newline at end of file diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/places/AppPlaceHistoryMapper.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/places/AppPlaceHistoryMapper.java deleted file mode 100644 index 9fc97c75b..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/places/AppPlaceHistoryMapper.java +++ /dev/null @@ -1,8 +0,0 @@ -//package org.platformlayer.ui.web.client.places; -// -//import com.google.gwt.place.shared.PlaceHistoryMapper; -//import com.google.gwt.place.shared.WithTokenizers; -// -//@WithTokenizers({ EditItemPlace.Tokenizer.class }) -//public interface AppPlaceHistoryMapper extends PlaceHistoryMapper { -// } \ No newline at end of file diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/places/EditItemPlace.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/places/EditItemPlace.java deleted file mode 100644 index 90c35b964..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/places/EditItemPlace.java +++ /dev/null @@ -1,28 +0,0 @@ -//package org.platformlayer.ui.web.client.places; -// -//import com.google.gwt.place.shared.Place; -//import com.google.gwt.place.shared.PlaceTokenizer; -// -//public class EditItemPlace extends Place { -// private String helloName; -// -// public EditItemPlace(String token) { -// this.helloName = token; -// } -// -// public String getHelloName() { -// return helloName; -// } -// -// public static class Tokenizer implements PlaceTokenizer { -// @Override -// public String getToken(EditItemPlace place) { -// return place.getHelloName(); -// } -// -// @Override -// public EditItemPlace getPlace(String token) { -// return new EditItemPlace(token); -// } -// } -// } diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/AptCacheServiceEditor.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/AptCacheServiceEditor.java deleted file mode 100644 index 4d9108cb6..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/AptCacheServiceEditor.java +++ /dev/null @@ -1,67 +0,0 @@ -///* -// * Copyright 2010 Google Inc. -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); you may not -// * use this file except in compliance with the License. You may obtain a copy of -// * the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * 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 org.platformlayer.ui.web.client.widgets; -// -//import org.platformlayer.ui.web.shared.AptCacheServiceProxy; -// -//import com.google.gwt.core.client.GWT; -//import com.google.gwt.editor.client.Editor; -//import com.google.gwt.editor.ui.client.ValueBoxEditorDecorator; -//import com.google.gwt.uibinder.client.UiBinder; -//import com.google.gwt.uibinder.client.UiField; -//import com.google.gwt.user.client.ui.Composite; -//import com.google.gwt.user.client.ui.Widget; -// -///** -// * Edits People. -// */ -//public class AptCacheServiceEditor extends Composite implements Editor { -// interface Binder extends UiBinder { -// } -// -// // @UiField -// // AddressEditor address; -// -// @UiField -// ValueBoxEditorDecorator dnsName; -// -// // @UiField(provided = true) -// // MentorSelector mentor; -// -// // @UiField -// // ValueBoxEditorDecorator name; -// // -// // @UiField -// // ValueBoxEditorDecorator note; -// // -// // @UiField -// // Focusable nameBox; -// -// // @UiField(provided = true) -// // ScheduleEditor classSchedule; -// -// public AptCacheServiceEditor() { -// initWidget(GWT. create(Binder.class).createAndBindUi(this)); -// } -// -// public void focus() { -// // Scheduler.get().scheduleDeferred(new ScheduledCommand() { -// // public void execute() { -// // nameBox.setFocus(true); -// // } -// // }); -// } -// } diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/AptCacheServiceEditor.ui.xml b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/AptCacheServiceEditor.ui.xml deleted file mode 100644 index cbf4074bf..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/AptCacheServiceEditor.ui.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - -
- DNS Name: - - - - - -
-
- -
-
\ No newline at end of file diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/AptCacheServiceGrid.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/AptCacheServiceGrid.java deleted file mode 100644 index 349aea00c..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/AptCacheServiceGrid.java +++ /dev/null @@ -1,209 +0,0 @@ -///* -// * Copyright 2010 Google Inc. -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); you may not -// * use this file except in compliance with the License. You may obtain a copy of -// * the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * 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 org.platformlayer.ui.web.client.widgets; -// -//import java.util.Collections; -//import java.util.List; -// -//import org.platformlayer.ui.web.client.events.EditAptCacheServiceEvent; -//import org.platformlayer.ui.web.shared.AptCacheServiceProxy; -//import org.platformlayer.ui.web.shared.PlatformLayerRequestFactory; -//import org.platformlayer.ui.web.shared.PlatformLayerRequestFactory.AptCacheServiceRequest; -// -//import com.google.gwt.cell.client.TextCell; -//import com.google.gwt.core.client.GWT; -//import com.google.gwt.event.dom.client.ClickEvent; -//import com.google.gwt.event.shared.EventBus; -//import com.google.gwt.uibinder.client.UiBinder; -//import com.google.gwt.uibinder.client.UiField; -//import com.google.gwt.uibinder.client.UiHandler; -//import com.google.gwt.user.cellview.client.Column; -//import com.google.gwt.user.cellview.client.DataGrid; -//import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy; -//import com.google.gwt.user.cellview.client.SimplePager; -//import com.google.gwt.user.client.ui.DockLayoutPanel; -//import com.google.gwt.user.client.ui.Widget; -//import com.google.gwt.view.client.Range; -//import com.google.gwt.view.client.RangeChangeEvent; -//import com.google.gwt.view.client.SelectionChangeEvent; -//import com.google.web.bindery.requestfactory.shared.EntityProxyChange; -//import com.google.web.bindery.requestfactory.shared.EntityProxyId; -//import com.google.web.bindery.requestfactory.shared.Receiver; -//import com.google.web.bindery.requestfactory.shared.WriteOperation; -// -///** -// * A paging table with summaries of all known people. -// */ -//public class AptCacheServiceGrid extends GridBase { -// -// interface Binder extends UiBinder { -// } -// -// private class DescriptionColumn extends Column { -// public DescriptionColumn() { -// super(new TextCell()); -// } -// -// @Override -// public String getValue(AptCacheServiceProxy object) { -// return object.getDnsName(); -// } -// } -// -// @UiField -// DockLayoutPanel dock; -// -// @UiField(provided = true) -// SimplePager pager = new SimplePager(); -// -// @UiField(provided = true) -// DataGrid table; -// -// @Override -// protected DataGrid getTable() { -// // TODO: Can UiFields be inherited?? -// return table; -// } -// -// private final EventBus eventBus; -// private int lastFetch; -// private final int numRows; -// private final PlatformLayerRequestFactory requestFactory; -// -// public AptCacheServiceGrid(EventBus eventBus, PlatformLayerRequestFactory requestFactory, int numRows) { -// this.eventBus = eventBus; -// this.requestFactory = requestFactory; -// this.numRows = numRows; -// -// table = new DataGrid(numRows, GWT. create(TableResources.class)); -// initWidget(GWT. create(Binder.class).createAndBindUi(this)); -// -// // Column nameColumn = new NameColumn(); -// // table.addColumn(nameColumn, "Name"); -// // table.setColumnWidth(nameColumn, "25ex"); -// Column descriptionColumn = new DescriptionColumn(); -// table.addColumn(descriptionColumn, "Description"); -// table.setColumnWidth(descriptionColumn, "40ex"); -// // table.addColumn(new ScheduleColumn(), "Schedule"); -// table.setRowCount(numRows, false); -// table.setSelectionModel(selectionModel); -// table.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.DISABLED); -// -// EntityProxyChange.registerForProxyType(eventBus, AptCacheServiceProxy.class, new EntityProxyChange.Handler() { -// @Override -// public void onProxyChange(EntityProxyChange event) { -// AptCacheServiceGrid.this.onPersonChanged(event); -// } -// }); -// -// // FilterChangeEvent.register(eventBus, new FilterChangeEvent.Handler() { -// // @Override -// // public void onFilterChanged(FilterChangeEvent e) { -// // filter.set(e.getDay(), e.isSelected()); -// // if (!pending) { -// // pending = true; -// // Scheduler.get().scheduleFinally(new ScheduledCommand() { -// // @Override -// // public void execute() { -// // pending = false; -// // fetch(0); -// // } -// // }); -// // } -// // } -// // }); -// -// selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() { -// @Override -// public void onSelectionChange(SelectionChangeEvent event) { -// AptCacheServiceGrid.this.refreshSelection(); -// } -// }); -// -// fetch(0); -// } -// -// @UiHandler("create") -// void onCreate(ClickEvent event) { -// AptCacheServiceRequest context = requestFactory.aptCacheRequest(); -// // AptCacheServiceProxy aptCache = context.create(AptCacheServiceProxy.class); -// -// // AddressProxy address = context.create(AddressProxy.class); -// // ScheduleProxy schedule = context.create(ScheduleProxy.class); -// // schedule.setTimeSlots(new ArrayList()); -// AptCacheServiceProxy aptCache = context.edit(context.create(AptCacheServiceProxy.class)); -// // person.setAddress(address); -// // person.setClassSchedule(schedule); -// context.persist(aptCache); -// eventBus.fireEvent(new EditAptCacheServiceEvent(aptCache, context)); -// } -// -// void onPersonChanged(EntityProxyChange event) { -// if (WriteOperation.PERSIST.equals(event.getWriteOperation())) { -// // Re-fetch if we're already displaying the last page -// if (table.isRowCountExact()) { -// fetch(lastFetch + 1); -// } -// } -// if (WriteOperation.UPDATE.equals(event.getWriteOperation())) { -// EntityProxyId personId = event.getProxyId(); -// -// // Is the changing record onscreen? -// int displayOffset = offsetOf(personId); -// if (displayOffset != -1) { -// // Record is onscreen and may differ from our data -// requestFactory.find(personId).fire(new Receiver() { -// @Override -// public void onSuccess(AptCacheServiceProxy person) { -// // Re-check offset in case of changes while waiting for data -// int offset = offsetOf(person.stableId()); -// if (offset != -1) { -// table.setRowData(table.getPageStart() + offset, Collections.singletonList(person)); -// } -// } -// }); -// } -// } -// } -// -// @UiHandler("table") -// void onRangeChange(RangeChangeEvent event) { -// Range r = event.getNewRange(); -// int start = r.getStart(); -// -// fetch(start); -// } -// -// private void fetch(final int start) { -// lastFetch = start; -// requestFactory.aptCacheRequest().findAll(/* start, numRows, filter */).fire(new Receiver>() { -// @Override -// public void onSuccess(List response) { -// if (lastFetch != start) { -// return; -// } -// -// int responses = response.size(); -// table.setRowData(start, response); -// pager.setPageStart(start); -// if (start == 0 || !table.isRowCountExact()) { -// table.setRowCount(start + responses, responses < numRows); -// } -// } -// }); -// } -// -// } diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/AptCacheServiceGrid.ui.xml b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/AptCacheServiceGrid.ui.xml deleted file mode 100644 index 5b3abd828..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/AptCacheServiceGrid.ui.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - .displayInline { - display: inline; - } - - .table { - width: 100%; - table-layout: fixed; - } - - - - - - - - - - - - New Apt-Cache - - - - - - - - - \ No newline at end of file diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/DataGridPatch.css b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/DataGridPatch.css deleted file mode 100644 index 1f40459d3..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/DataGridPatch.css +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ -/* - * This file is used by SummaryWidget to patch the CSS styles used in DataGrid. - * The style rules defined in this file are appended to the default styles in - * DataGrid's CssResource. If there are conflicts, the styles defined in this - * file take precedence over the defaults because these styles appear after the - * default styles. - */ -.dataGridCell { - cursor: pointer; -} \ No newline at end of file diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/GridBase.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/GridBase.java deleted file mode 100644 index a24efcd9c..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/GridBase.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.platformlayer.ui.web.client.widgets; - -import java.util.List; - -import com.google.gwt.resources.client.CssResource; -import com.google.gwt.user.cellview.client.DataGrid; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.view.client.SingleSelectionModel; -import com.google.web.bindery.requestfactory.shared.EntityProxy; -import com.google.web.bindery.requestfactory.shared.EntityProxyId; - -public abstract class GridBase extends Composite { - protected final SingleSelectionModel selectionModel = new SingleSelectionModel(); - - public interface Style extends CssResource { - } - - public interface TableResources extends DataGrid.Resources { - @Override - @Source(value = { DataGrid.Style.DEFAULT_CSS, "DataGridPatch.css" }) - DataGrid.Style dataGridStyle(); - } - - protected int offsetOf(EntityProxyId personId) { - List displayedItems = getTable().getVisibleItems(); - for (int offset = 0, j = displayedItems.size(); offset < j; offset++) { - if (personId.equals(displayedItems.get(offset).stableId())) { - return offset; - } - } - return -1; - } - - protected abstract DataGrid getTable(); - - protected void refreshSelection() { - T person = selectionModel.getSelectedObject(); - if (person == null) { - return; - } - // eventBus.fireEvent(new EditPersonEvent(person)); - selectionModel.setSelected(person, false); - } - -} diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/MainPanel.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/MainPanel.java deleted file mode 100644 index 8d2e58ab7..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/MainPanel.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.platformlayer.ui.web.client.widgets; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.Widget; - -public class MainPanel extends Composite { - - interface Binder extends UiBinder { - } - - public MainPanel() { - initWidget(GWT. create(Binder.class).createAndBindUi(this)); - } - -} diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/MainPanel.ui.xml b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/MainPanel.ui.xml deleted file mode 100644 index 22a60374a..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/MainPanel.ui.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/ServiceTabs.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/ServiceTabs.java deleted file mode 100644 index 0f71aba6a..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/ServiceTabs.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.platformlayer.ui.web.client.widgets; - -import org.platformlayer.service.aptcache.client.ServicePanel; -import org.platformlayer.service.dns.client.DnsServicePanel; -import org.platformlayer.service.dnsresolver.client.DnsResolverServicePanel; -import org.platformlayer.service.openldap.client.LdapProviderPanel; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.resources.client.CssResource; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.Label; -import com.google.gwt.user.client.ui.LazyPanel; -import com.google.gwt.user.client.ui.TabLayoutPanel; -import com.google.gwt.user.client.ui.Widget; - -public class ServiceTabs extends Composite { - - interface Binder extends UiBinder { - } - - interface Style extends CssResource { - } - - @UiField - TabLayoutPanel tabs; - - public ServiceTabs() { - initWidget(GWT. create(Binder.class).createAndBindUi(this)); - - buildTabs(); - - tabs.selectTab(0); - } - - private void buildTabs() { - { - LazyPanel lazyPanel = new LazyPanel() { - @Override - protected Widget createWidget() { - return new DnsServicePanel(); - } - }; - Label label = new Label("DNS"); - tabs.add(lazyPanel, label); - } - - { - LazyPanel lazyPanel = new LazyPanel() { - @Override - protected Widget createWidget() { - return new DnsResolverServicePanel(); - } - }; - Label label = new Label("DNS Resolvers"); - tabs.add(lazyPanel, label); - } - - { - LazyPanel lazyPanel = new LazyPanel() { - @Override - protected Widget createWidget() { - return new ServicePanel(); - } - }; - Label label = new Label("APT Cache"); - tabs.add(lazyPanel, label); - } - - { - LazyPanel lazyPanel = new LazyPanel() { - @Override - protected Widget createWidget() { - return new LdapProviderPanel(); - } - }; - Label label = new Label("LDAP"); - tabs.add(lazyPanel, label); - } - } - - // private void fetch() { - // requestFactory.serviceInfoRequest().findAll(/* start, numRows, filter */).fire(new Receiver>() { - // @Override - // public void onSuccess(List response) { - // for (final ServiceInfoProxy service : response) { - // LazyPanel lazyPanel = new LazyPanel() { - // - // @Override - // protected Widget createWidget() { - // return new ServiceWidget(service); - // } - // }; - // Label label = new Label(service.getDescription()); - // tabs.add(label, lazyPanel); - // } - // } - // }); - // } -} diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/ServiceTabs.ui.xml b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/ServiceTabs.ui.xml deleted file mode 100644 index fb3affcd8..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/ServiceTabs.ui.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/ServiceWidget.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/ServiceWidget.java deleted file mode 100644 index ca882430a..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/ServiceWidget.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.platformlayer.ui.web.client.widgets; - -import org.platformlayer.ui.web.shared.ServiceInfoProxy; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.resources.client.CssResource; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.TabLayoutPanel; -import com.google.gwt.user.client.ui.Widget; - -public class ServiceWidget extends Composite { - interface Binder extends UiBinder { - } - - interface Style extends CssResource { - } - - final ServiceInfoProxy service; - - @UiField - TabLayoutPanel tabs; - - public ServiceWidget(ServiceInfoProxy service) { - this.service = service; - initWidget(GWT. create(Binder.class).createAndBindUi(this)); - - // fetch(); - - } - -} diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/ServiceWidget.ui.xml b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/ServiceWidget.ui.xml deleted file mode 100644 index 6fa2d821b..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/ServiceWidget.ui.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/SummaryWidget.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/SummaryWidget.java deleted file mode 100644 index ebf52bb11..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/SummaryWidget.java +++ /dev/null @@ -1,255 +0,0 @@ -///* -// * Copyright 2010 Google Inc. -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); you may not -// * use this file except in compliance with the License. You may obtain a copy of -// * the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * 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 org.platformlayer.ui.web.client.widgets; -// -//import java.util.Collections; -//import java.util.List; -// -//import org.platformlayer.ui.web.shared.PlatformLayerRequestFactory; -//import org.platformlayer.ui.web.shared.PlatformLayerRequestFactory.ServiceInfoRequest; -//import org.platformlayer.ui.web.shared.ServiceInfoProxy; -// -//import com.google.gwt.cell.client.TextCell; -//import com.google.gwt.core.client.GWT; -//import com.google.gwt.event.dom.client.ClickEvent; -//import com.google.gwt.event.shared.EventBus; -//import com.google.gwt.resources.client.CssResource; -//import com.google.gwt.uibinder.client.UiBinder; -//import com.google.gwt.uibinder.client.UiField; -//import com.google.gwt.uibinder.client.UiHandler; -//import com.google.gwt.user.cellview.client.Column; -//import com.google.gwt.user.cellview.client.DataGrid; -//import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy; -//import com.google.gwt.user.cellview.client.SimplePager; -//import com.google.gwt.user.client.ui.Composite; -//import com.google.gwt.user.client.ui.DockLayoutPanel; -//import com.google.gwt.user.client.ui.Widget; -//import com.google.gwt.view.client.Range; -//import com.google.gwt.view.client.RangeChangeEvent; -//import com.google.gwt.view.client.SelectionChangeEvent; -//import com.google.gwt.view.client.SingleSelectionModel; -//import com.google.web.bindery.requestfactory.shared.EntityProxyChange; -//import com.google.web.bindery.requestfactory.shared.EntityProxyId; -//import com.google.web.bindery.requestfactory.shared.Receiver; -//import com.google.web.bindery.requestfactory.shared.WriteOperation; -// -///** -// * A paging table with summaries of all known people. -// */ -//public class SummaryWidget extends Composite { -// -// interface Binder extends UiBinder { -// } -// -// interface Style extends CssResource { -// } -// -// interface TableResources extends DataGrid.Resources { -// @Override -// @Source(value = { DataGrid.Style.DEFAULT_CSS, "DataGridPatch.css" }) -// DataGrid.Style dataGridStyle(); -// } -// -// private class DescriptionColumn extends Column { -// public DescriptionColumn() { -// super(new TextCell()); -// } -// -// @Override -// public String getValue(ServiceInfoProxy object) { -// return object.getDescription(); -// } -// } -// -// // private class NameColumn extends Column { -// // public NameColumn() { -// // super(new TextCell()); -// // } -// // -// // @Override -// // public String getValue(PersonProxy object) { -// // return object.getName(); -// // } -// // } -// // -// // private class ScheduleColumn extends Column { -// // public ScheduleColumn() { -// // super(new TextCell()); -// // } -// // -// // @Override -// // public String getValue(PersonProxy object) { -// // return object.getScheduleDescription(); -// // } -// // } -// -// @UiField -// DockLayoutPanel dock; -// -// @UiField(provided = true) -// SimplePager pager = new SimplePager(); -// -// @UiField(provided = true) -// DataGrid table; -// -// private final EventBus eventBus; -// // private List filter = new ArrayList(ALL_DAYS); -// private int lastFetch; -// private final int numRows; -// private boolean pending; -// private final PlatformLayerRequestFactory requestFactory; -// private final SingleSelectionModel selectionModel = new SingleSelectionModel(); -// -// public SummaryWidget(EventBus eventBus, PlatformLayerRequestFactory requestFactory, int numRows) { -// this.eventBus = eventBus; -// this.requestFactory = requestFactory; -// this.numRows = numRows; -// -// table = new DataGrid(numRows, GWT. create(TableResources.class)); -// initWidget(GWT. create(Binder.class).createAndBindUi(this)); -// -// // Column nameColumn = new NameColumn(); -// // table.addColumn(nameColumn, "Name"); -// // table.setColumnWidth(nameColumn, "25ex"); -// Column descriptionColumn = new DescriptionColumn(); -// table.addColumn(descriptionColumn, "Description"); -// table.setColumnWidth(descriptionColumn, "40ex"); -// // table.addColumn(new ScheduleColumn(), "Schedule"); -// table.setRowCount(numRows, false); -// table.setSelectionModel(selectionModel); -// table.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.DISABLED); -// -// EntityProxyChange.registerForProxyType(eventBus, ServiceInfoProxy.class, new EntityProxyChange.Handler() { -// @Override -// public void onProxyChange(EntityProxyChange event) { -// SummaryWidget.this.onPersonChanged(event); -// } -// }); -// -// // FilterChangeEvent.register(eventBus, new FilterChangeEvent.Handler() { -// // @Override -// // public void onFilterChanged(FilterChangeEvent e) { -// // filter.set(e.getDay(), e.isSelected()); -// // if (!pending) { -// // pending = true; -// // Scheduler.get().scheduleFinally(new ScheduledCommand() { -// // @Override -// // public void execute() { -// // pending = false; -// // fetch(0); -// // } -// // }); -// // } -// // } -// // }); -// -// selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() { -// @Override -// public void onSelectionChange(SelectionChangeEvent event) { -// SummaryWidget.this.refreshSelection(); -// } -// }); -// -// fetch(0); -// } -// -// @UiHandler("create") -// void onCreate(ClickEvent event) { -// ServiceInfoRequest context = requestFactory.serviceInfoRequest(); -// // AddressProxy address = context.create(AddressProxy.class); -// // ScheduleProxy schedule = context.create(ScheduleProxy.class); -// // schedule.setTimeSlots(new ArrayList()); -// ServiceInfoProxy person = context.edit(context.create(ServiceInfoProxy.class)); -// // person.setAddress(address); -// // person.setClassSchedule(schedule); -// // context.persist().using(person); -// // eventBus.fireEvent(new EditPersonEvent(person, context)); -// } -// -// void onPersonChanged(EntityProxyChange event) { -// if (WriteOperation.PERSIST.equals(event.getWriteOperation())) { -// // Re-fetch if we're already displaying the last page -// if (table.isRowCountExact()) { -// fetch(lastFetch + 1); -// } -// } -// if (WriteOperation.UPDATE.equals(event.getWriteOperation())) { -// EntityProxyId personId = event.getProxyId(); -// -// // Is the changing record onscreen? -// int displayOffset = offsetOf(personId); -// if (displayOffset != -1) { -// // Record is onscreen and may differ from our data -// requestFactory.find(personId).fire(new Receiver() { -// @Override -// public void onSuccess(ServiceInfoProxy person) { -// // Re-check offset in case of changes while waiting for data -// int offset = offsetOf(person.stableId()); -// if (offset != -1) { -// table.setRowData(table.getPageStart() + offset, Collections.singletonList(person)); -// } -// } -// }); -// } -// } -// } -// -// @UiHandler("table") -// void onRangeChange(RangeChangeEvent event) { -// Range r = event.getNewRange(); -// int start = r.getStart(); -// -// fetch(start); -// } -// -// void refreshSelection() { -// ServiceInfoProxy person = selectionModel.getSelectedObject(); -// if (person == null) { -// return; -// } -// // eventBus.fireEvent(new EditPersonEvent(person)); -// selectionModel.setSelected(person, false); -// } -// -// private void fetch(final int start) { -// lastFetch = start; -// requestFactory.serviceInfoRequest().findAll(/* start, numRows, filter */).fire(new Receiver>() { -// @Override -// public void onSuccess(List response) { -// if (lastFetch != start) { -// return; -// } -// -// int responses = response.size(); -// table.setRowData(start, response); -// pager.setPageStart(start); -// if (start == 0 || !table.isRowCountExact()) { -// table.setRowCount(start + responses, responses < numRows); -// } -// } -// }); -// } -// -// private int offsetOf(EntityProxyId personId) { -// List displayedItems = table.getVisibleItems(); -// for (int offset = 0, j = displayedItems.size(); offset < j; offset++) { -// if (personId.equals(displayedItems.get(offset).stableId())) { -// return offset; -// } -// } -// return -1; -// } -// } diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/SummaryWidget.ui.xml b/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/SummaryWidget.ui.xml deleted file mode 100644 index f0f3406a6..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/client/widgets/SummaryWidget.ui.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - .displayInline { - display: inline; - } - - .table { - width: 100%; - table-layout: fixed; - } - - - - - - - - - - - - New - Person - - - - - - - - - \ No newline at end of file diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/AptCacheServiceGwtService.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/server/AptCacheServiceGwtService.java deleted file mode 100644 index b1d23f6bb..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/AptCacheServiceGwtService.java +++ /dev/null @@ -1,65 +0,0 @@ -//package org.platformlayer.ui.web.server; -// -//import java.util.List; -// -//import javax.inject.Inject; -//import javax.inject.Provider; -// -//import org.platformlayer.model.Authentication; -//import org.platformlayer.ops.OpsException; -//import org.platformlayer.service.aptcache.model.AptCacheService; -//import org.platformlayer.ui.web.server.inject.PlatformLayerLiveObjects; -//import org.platformlayer.web.ContextMap; -//import org.platformlayer.xaas.services.ServiceProviderDictionary; -//import org.platformlayer.xaas.web.resources.ItemService; -// -//import com.google.web.bindery.requestfactory.server.RequestFactoryServlet; -// -//public class AptCacheServiceGwtService { -// -// @Inject -// ItemService itemService; -// -// @Inject -// ServiceProviderDictionary serviceProviderDictionary; -// -// @Inject -// Provider contextMapProvider; -// -// public List findAll() throws OpsException { -// Authentication authentication = getAuthentication(); -// -// return itemService.findAll(authentication, AptCacheService.class); -// } -// -// public AptCacheService persist(AptCacheService managedItem) throws OpsException { -// Authentication authentication = getAuthentication(); -// -// AptCacheService aptCacheService = itemService.createItem(authentication, managedItem); -// -// PlatformLayerLiveObjects liveObjects = PlatformLayerLiveObjects.get(contextMapProvider); -// liveObjects.notifyCreated(aptCacheService, aptCacheService.getId()); -// -// return aptCacheService; -// -// // if (person.getId() == null) { -// // person.setId(Long.toString(++serial)); -// // } -// // person.setVersion(person.getVersion() + 1); -// // if (person.getClassSchedule() != null) { -// // scheduleStore.persist(person.getClassSchedule()); -// // } -// // Person existing = people.get(person.getId()); -// // if (existing != null) { -// // existing.copyFrom(person); -// // } else { -// // people.put(person.getId(), person); -// // } -// } -// -// private Authentication getAuthentication() { -// ContextMap contextMap = ContextMap.get(RequestFactoryServlet.getThreadLocalRequest()); -// Authentication authentication = contextMap.getTyped(Authentication.class); -// return authentication; -// } -// } diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/AptCacheServiceLocator.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/server/AptCacheServiceLocator.java deleted file mode 100644 index 0392a4aa5..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/AptCacheServiceLocator.java +++ /dev/null @@ -1,44 +0,0 @@ -//package org.platformlayer.ui.web.server; -// -//import org.platformlayer.ids.ServiceType; -//import org.platformlayer.service.aptcache.v1.AptCacheService; -// -//import com.google.web.bindery.requestfactory.shared.Locator; -// -//public class AptCacheServiceLocator extends Locator { -// -// @Override -// public AptCacheService create(Class clazz) { -// if (!clazz.equals(AptCacheService.class)) -// throw new IllegalArgumentException(); -// return new AptCacheService(); -// } -// -// @Override -// public AptCacheService find(Class clazz, String id) { -// if (!clazz.equals(AptCacheService.class)) -// throw new IllegalArgumentException(); -// return ServerContext.get().findServiceInfo(new ServiceType(id)); -// } -// -// @Override -// public Class getDomainType() { -// return AptCacheService.class; -// } -// -// @Override -// public String getId(AptCacheService domainObject) { -// return domainObject.getKey(); -// } -// -// @Override -// public Class getIdType() { -// return String.class; -// } -// -// @Override -// public Object getVersion(AptCacheService domainObject) { -// return 0; -// } -// -// } diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/DefaultWrapperServlet.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/server/DefaultWrapperServlet.java deleted file mode 100644 index c65aa8e03..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/DefaultWrapperServlet.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.platformlayer.ui.web.server; - -import java.io.IOException; - -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; - -public class DefaultWrapperServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - - public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - RequestDispatcher rd = getServletContext().getNamedDispatcher("default"); - - HttpServletRequest wrapped = new HttpServletRequestWrapper(req) { - public String getServletPath() { - return ""; - } - }; - - rd.forward(wrapped, resp); - } -} \ No newline at end of file diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/DnsRecordGwtService.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/server/DnsRecordGwtService.java deleted file mode 100644 index 61ce810f6..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/DnsRecordGwtService.java +++ /dev/null @@ -1,18 +0,0 @@ -//package org.platformlayer.ui.web.server; -// -//import org.platformlayer.service.dns.model.DnsRecord; -// -//public class DnsRecordGwtService extends GwtServiceBase { -// -// public DnsRecordGwtService() { -// super(DnsRecord.class); -// } -// -// // public List findAll() throws OpsException { -// // return findAll(DnsRecord.class); -// // } -// -// // public DnsRecord persist(DnsRecord managedItem) throws OpsException { -// // return persist2(managedItem); -// // } -// } diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/DnsServerGwtService.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/server/DnsServerGwtService.java deleted file mode 100644 index f19408c08..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/DnsServerGwtService.java +++ /dev/null @@ -1,11 +0,0 @@ -//package org.platformlayer.ui.web.server; -// -//import org.platformlayer.service.dns.model.DnsServer; -// -//public class DnsServerGwtService extends GwtServiceBase { -// -// public DnsServerGwtService() { -// super(DnsServer.class); -// } -// -// } \ No newline at end of file diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/DnsZoneGwtService.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/server/DnsZoneGwtService.java deleted file mode 100644 index a8b9bb453..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/DnsZoneGwtService.java +++ /dev/null @@ -1,18 +0,0 @@ -//package org.platformlayer.ui.web.server; -// -//import org.platformlayer.service.dns.model.DnsZone; -// -//public class DnsZoneGwtService extends GwtServiceBase { -// -// public DnsZoneGwtService() { -// super(DnsZone.class); -// } -// -// // public List findAll() throws OpsException { -// // return findAll(DnsDomain.class); -// // } -// -// // public DnsDomain persist(DnsDomain managedItem) throws OpsException { -// // return persist2(managedItem); -// // } -// } diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/GenericRequestService.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/server/GenericRequestService.java deleted file mode 100644 index e4bb03b12..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/GenericRequestService.java +++ /dev/null @@ -1,42 +0,0 @@ -//package org.platformlayer.ui.web.server; -// -//import java.util.List; -// -//import javax.inject.Inject; -//import javax.inject.Provider; -// -//import org.platformlayer.core.model.ItemBase; -//import org.platformlayer.model.Authentication; -//import org.platformlayer.ops.OpsException; -//import org.platformlayer.ui.web.server.inject.PlatformLayerLiveObjects; -//import org.platformlayer.web.ContextMap; -//import org.platformlayer.xaas.web.resources.ItemService; -// -//public class GenericRequestService { -// -// @Inject -// ItemService itemService; -// -// @Inject -// Provider contextMapProvider; -// -// @Inject -// Provider authenticationProvider; -// -// public List findAll(Class proxyClass) throws OpsException { -// Authentication authentication = authenticationProvider.get(); -// -// return itemService.findAll(authentication, proxyClass); -// } -// -// public T persist(T managedItem) throws OpsException { -// Authentication authentication = authenticationProvider.get(); -// -// T created = itemService.createItem(authentication, managedItem); -// -// PlatformLayerLiveObjects liveObjects = PlatformLayerLiveObjects.get(contextMapProvider); -// liveObjects.notifyCreated(created, created.getId()); -// -// return created; -// } -// } \ No newline at end of file diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/GwtGuiceServletConfig.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/server/GwtGuiceServletConfig.java deleted file mode 100644 index 21e25f10c..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/GwtGuiceServletConfig.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.platformlayer.ui.web.server; - -import java.util.List; - -import org.platformlayer.xaas.GuiceServletConfig; - -import com.google.inject.Module; - -public class GwtGuiceServletConfig extends GuiceServletConfig { - - @Override - protected void addServletModule(List modules) { - modules.add(new GwtPlatformLayerServletModule()); - } -} diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/GwtPlatformLayerServletModule.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/server/GwtPlatformLayerServletModule.java deleted file mode 100644 index 3288850b5..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/GwtPlatformLayerServletModule.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.platformlayer.ui.web.server; - -import org.openstack.keystone.service.OpenstackAuthenticationFilterBase; -import org.platformlayer.ui.shared.server.inject.InjectedRequestFactoryServlet; -import org.platformlayer.ui.shared.server.inject.ServiceLayerDecoratorFactory; -import org.platformlayer.xaas.PlatformLayerServletModule; - -import com.google.web.bindery.requestfactory.server.DefaultExceptionHandler; -import com.google.web.bindery.requestfactory.server.ExceptionHandler; - -public class GwtPlatformLayerServletModule extends PlatformLayerServletModule { - @Override - protected void configureServlets() { - bind(ExceptionHandler.class).to(DefaultExceptionHandler.class); - bind(ServiceLayerDecoratorFactory.class).to(PlatformLayerServiceLayerDecoratorFactory.class); - - // Map params = Maps.newHashMap(); - // - // symbolMapsDirectory - // - // WEB-INF/classes/symbolMaps/ - // - bind(InjectedRequestFactoryServlet.class).asEagerSingleton(); - serve("/gwtRequest").with(InjectedRequestFactoryServlet.class); - - filter("/gwtRequest").through(OpenstackAuthenticationFilterBase.class); - - bind(ServerContextFilter.class).asEagerSingleton(); - - filter("/gwtRequest").through(ServerContextFilter.class); - - bind(DefaultWrapperServlet.class).asEagerSingleton(); - serve("/static/*").with(DefaultWrapperServlet.class); - - super.configureServlets(); - } -} diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/PlatformLayerServiceLayerDecoratorFactory.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/server/PlatformLayerServiceLayerDecoratorFactory.java deleted file mode 100644 index 81377f55b..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/PlatformLayerServiceLayerDecoratorFactory.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.platformlayer.ui.web.server; - -import org.platformlayer.ui.shared.server.inject.PlatformLayerServiceLayerDecorator; -import org.platformlayer.ui.shared.server.inject.ServiceLayerDecoratorFactory; - -public class PlatformLayerServiceLayerDecoratorFactory extends ServiceLayerDecoratorFactory { - - @Override - protected void addDecorators() { - addDecorator(PlatformLayerServiceLayerDecorator.class); - super.addDecorators(); - } - -} diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServerContext.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServerContext.java deleted file mode 100644 index 8c9ec9847..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServerContext.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.platformlayer.ui.web.server; - -import java.util.List; - -import javax.inject.Inject; - -import org.platformlayer.core.model.ServiceInfo; -import org.platformlayer.ids.ServiceType; -import org.platformlayer.xaas.services.ServiceProviderDictionary; - -import com.google.inject.Injector; - -public class ServerContext { - static ThreadLocal THREAD_CONTEXT = new ThreadLocal(); - - public static ServerContext get() { - return THREAD_CONTEXT.get(); - } - - public static void set(ServerContext serverContext) { - THREAD_CONTEXT.set(serverContext); - } - - @Inject - Injector injector; - - @Inject - ServiceProviderDictionary serviceDictionary; - - ServiceInfo findServiceInfo(ServiceType serviceType) { - boolean management = false; - - List allServices = serviceDictionary.getAllServices(management); - for (ServiceInfo service : allServices) { - if (service.getServiceType().equals(serviceType.getKey())) { - return service; - } - } - - return null; - } - - public T getInstance(Class clazz) { - return injector.getInstance(clazz); - } -} \ No newline at end of file diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServerContextFilter.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServerContextFilter.java deleted file mode 100644 index b4208219b..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServerContextFilter.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.platformlayer.ui.web.server; - -import java.io.IOException; - -import javax.inject.Inject; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import com.google.inject.Injector; - -public class ServerContextFilter implements Filter { - - @Inject - Injector injector; - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - ServerContext serverContext = injector.getInstance(ServerContext.class); - ServerContext.set(serverContext); - try { - chain.doFilter(request, response); - } finally { - ServerContext.set(null); - } - } - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - - } - - @Override - public void destroy() { - - } -} diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServerContextServiceLocator.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServerContextServiceLocator.java deleted file mode 100644 index 9dfb576cf..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServerContextServiceLocator.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.platformlayer.ui.web.server; - -import com.google.web.bindery.requestfactory.shared.ServiceLocator; - -public class ServerContextServiceLocator implements ServiceLocator { - - public Object getInstance(Class clazz) { - ServerContext gwtContext = ServerContext.get(); - return gwtContext.getInstance(clazz); - } - -} diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServiceInfoLocator.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServiceInfoLocator.java deleted file mode 100644 index 917ddc30c..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServiceInfoLocator.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.platformlayer.ui.web.server; - -import org.platformlayer.core.model.ServiceInfo; -import org.platformlayer.ids.ServiceType; - -import com.google.web.bindery.requestfactory.shared.Locator; - -public class ServiceInfoLocator extends Locator { - - @Override - public ServiceInfo create(Class clazz) { - if (!clazz.equals(ServiceInfo.class)) - throw new IllegalArgumentException(); - return new ServiceInfo(); - } - - @Override - public ServiceInfo find(Class clazz, String id) { - if (!clazz.equals(ServiceInfo.class)) - throw new IllegalArgumentException(); - return ServerContext.get().findServiceInfo(new ServiceType(id)); - } - - @Override - public Class getDomainType() { - return ServiceInfo.class; - } - - @Override - public String getId(ServiceInfo domainObject) { - return domainObject.getServiceType(); - } - - @Override - public Class getIdType() { - return String.class; - } - - @Override - public Object getVersion(ServiceInfo domainObject) { - return 0; - } - -} diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServiceInfoService.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServiceInfoService.java deleted file mode 100644 index 91b0eb8ae..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServiceInfoService.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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 org.platformlayer.ui.web.server; - -import java.util.List; - -import org.platformlayer.core.model.ServiceInfo; - -import com.google.common.collect.Lists; - -/** - * Service object for Schedule entities, used to demonstrate the use of non-static service objects with RequestFactory. RequestFactory finds this service via the {@link ServiceInfoServiceLocator}. - */ -public class ServiceInfoService { - - public List findAll() { - List serviceInfos = Lists.newArrayList(); - // serviceInfos.add(buildService("Service 1")); - // serviceInfos.add(buildService("Service 2")); - - ServerContext serverContext = ServerContext.get(); - boolean management = false; - List allServices = serverContext.serviceDictionary.getAllServices(management); - for (ServiceInfo service : allServices) { - serviceInfos.add(service); - } - - return serviceInfos; - } - - private ServiceInfo buildService(String description) { - ServiceInfo service1 = new ServiceInfo(); - service1.description = description; - return service1; - } -} diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServiceInfoServiceLocator.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServiceInfoServiceLocator.java deleted file mode 100644 index 7a813d9a9..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/server/ServiceInfoServiceLocator.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.platformlayer.ui.web.server; - -import com.google.web.bindery.requestfactory.shared.ServiceLocator; - -/** - * This class provides an example of implementing a ServiceLocator to allow RequestFactory to work with instances of service objects, instead of its default behavior of mapping service calls to static - * methods. - *

- * There is a reference to this class in an {@literal @}Service annotation in {@link com.google.gwt.sample.dynatablerf.shared.DynaTableRequestFactory} - */ -public class ServiceInfoServiceLocator implements ServiceLocator { - - public Object getInstance(Class clazz) { - return clazz.equals(ServiceInfoService.class) ? new ServiceInfoService() : null; - } - -} diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/AptCacheServiceLocator.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/AptCacheServiceLocator.java deleted file mode 100644 index 6f106ee6a..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/AptCacheServiceLocator.java +++ /dev/null @@ -1,43 +0,0 @@ -//package org.platformlayer.ui.web.shared; -// -//import org.platformlayer.service.aptcache.model.AptCacheService; -// -//import com.google.web.bindery.requestfactory.shared.Locator; -// -//public class AptCacheServiceLocator extends Locator { -// -// @Override -// public AptCacheService create(Class clazz) { -// return new AptCacheService(); -// } -// -// @Override -// public AptCacheService find(Class clazz, String id) { -// // TODO Auto-generated method stub -// return null; -// } -// -// @Override -// public Class getDomainType() { -// return AptCacheService.class; -// } -// -// @Override -// public String getId(AptCacheService domainObject) { -// // TODO Auto-generated method stub -// return null; -// } -// -// @Override -// public Class getIdType() { -// // TODO Auto-generated method stub -// return null; -// } -// -// @Override -// public Object getVersion(AptCacheService domainObject) { -// // TODO Auto-generated method stub -// return null; -// } -// -// } diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/AptCacheServiceProxy.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/AptCacheServiceProxy.java deleted file mode 100644 index bad128008..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/AptCacheServiceProxy.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.platformlayer.ui.web.shared; - -import org.platformlayer.service.aptcache.model.AptCacheService; - -import com.google.web.bindery.requestfactory.shared.EntityProxy; -import com.google.web.bindery.requestfactory.shared.EntityProxyId; -import com.google.web.bindery.requestfactory.shared.ProxyFor; -import com.google.web.bindery.requestfactory.shared.SkipInterfaceValidation; - -@ProxyFor(value = AptCacheService.class /* , locator = AptCacheServiceLocator.class */) -@SkipInterfaceValidation -// @SkipInterfaceValidation as we rely on PlatformLayer ServiceLayerDecorator -public interface AptCacheServiceProxy extends EntityProxy { - // Boilerplate - EntityProxyId stableId(); - - // Getters / Setters - String getDnsName(); - - void setDnsName(String dnsName); -} diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/DnsRecordProxy.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/DnsRecordProxy.java deleted file mode 100644 index f68b8ce95..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/DnsRecordProxy.java +++ /dev/null @@ -1,65 +0,0 @@ -//package org.platformlayer.ui.web.shared; -// -//import java.util.List; -// -//import org.platformlayer.service.dns.model.DnsRecord; -//import org.platformlayer.ui.web.client.commons.Accessor; -// -//import com.google.web.bindery.requestfactory.shared.EntityProxy; -//import com.google.web.bindery.requestfactory.shared.EntityProxyId; -//import com.google.web.bindery.requestfactory.shared.ProxyFor; -//import com.google.web.bindery.requestfactory.shared.SkipInterfaceValidation; -// -//@ProxyFor(value = DnsRecord.class) -//@SkipInterfaceValidation -//// @SkipInterfaceValidation as we rely on PlatformLayer ServiceLayerDecorator -//public interface DnsRecordProxy extends EntityProxy { -// // Boilerplate -// EntityProxyId stableId(); -// -// // Getters / Setters -// String getDnsName(); -// -// void setDnsName(String dnsName); -// -// String getRecordType(); -// -// void setRecordType(String v); -// -// List getAddress(); -// -// void setAddress(List v); -// -// static final Accessor DnsName = new Accessor() { -// public String get(DnsRecordProxy o) { -// return o.getDnsName(); -// } -// -// @Override -// public void set(DnsRecordProxy o, String value) { -// o.setDnsName(value); -// } -// }; -// -// static final Accessor RecordType = new Accessor() { -// public String get(DnsRecordProxy o) { -// return o.getRecordType(); -// } -// -// @Override -// public void set(DnsRecordProxy o, String value) { -// o.setRecordType(value); -// } -// }; -// -// static final Accessor> Address = new Accessor>() { -// public List get(DnsRecordProxy o) { -// return o.getAddress(); -// } -// -// @Override -// public void set(DnsRecordProxy o, List value) { -// o.setAddress(value); -// } -// }; -// } diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/DnsServerProxy.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/DnsServerProxy.java deleted file mode 100644 index 92be08f29..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/DnsServerProxy.java +++ /dev/null @@ -1,77 +0,0 @@ -//package org.platformlayer.ui.web.shared; -// -//import org.platformlayer.service.dns.client.DnsServerEditor; -//import org.platformlayer.service.dns.model.DnsServer; -//import org.platformlayer.ui.web.client.App; -//import org.platformlayer.ui.web.client.commons.Accessor; -//import org.platformlayer.ui.web.client.model.DomainModel; -//import org.platformlayer.ui.web.server.DnsServerGwtService; -//import org.platformlayer.ui.web.server.inject.InjectingServiceLocator; -// -//import com.google.gwt.core.client.GWT; -//import com.google.gwt.editor.client.Editor; -//import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryEditorDriver; -//import com.google.web.bindery.requestfactory.shared.EntityProxy; -//import com.google.web.bindery.requestfactory.shared.EntityProxyId; -//import com.google.web.bindery.requestfactory.shared.ProxyFor; -//import com.google.web.bindery.requestfactory.shared.Request; -//import com.google.web.bindery.requestfactory.shared.RequestContext; -//import com.google.web.bindery.requestfactory.shared.Service; -//import com.google.web.bindery.requestfactory.shared.SkipInterfaceValidation; -// -//@ProxyFor(value = DnsServer.class) -//@SkipInterfaceValidation -//// @SkipInterfaceValidation as we rely on PlatformLayer ServiceLayerDecorator -//public interface DnsServerProxy extends EntityProxy { -// // Boilerplate -// EntityProxyId stableId(); -// -// // Getters / Setters -// String getDnsName(); -// -// void setDnsName(String dnsName); -// -// static final Accessor DnsName = new Accessor() { -// @Override -// public String get(DnsServerProxy o) { -// return o.getDnsName(); -// } -// -// @Override -// public void set(DnsServerProxy o, String value) { -// o.setDnsName(value); -// } -// }; -// -// @Service(value = DnsServerGwtService.class, locator = InjectingServiceLocator.class) -// @SkipInterfaceValidation -// public interface DnsServerRequest extends RequestContext, BaseEntityRequest { -// Request persist(DnsServerProxy proxy); -// } -// -// public static interface EditorDriver extends RequestFactoryEditorDriver { -// -// } -// -// static final DomainModel Model = new DomainModel(DnsServerProxy.class) { -// @Override -// public Editor buildEditor() { -// return new DnsServerEditor(); -// } -// -// @Override -// public DnsServerRequest context() { -// return App.injector.getRequestFactory().dnsServerRequest(); -// } -// -// @Override -// public void persist(DnsServerRequest context, DnsServerProxy item) { -// context.persist(item); -// } -// -// @Override -// public RequestFactoryEditorDriver> buildEditorDriver() { -// return GWT.create(EditorDriver.class); -// } -// }; -// } diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/DnsZoneProxy.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/DnsZoneProxy.java deleted file mode 100644 index d7d7dfcf0..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/DnsZoneProxy.java +++ /dev/null @@ -1,34 +0,0 @@ -//package org.platformlayer.ui.web.shared; -// -//import org.platformlayer.service.dns.model.DnsZone; -//import org.platformlayer.ui.web.client.commons.Accessor; -// -//import com.google.web.bindery.requestfactory.shared.EntityProxy; -//import com.google.web.bindery.requestfactory.shared.EntityProxyId; -//import com.google.web.bindery.requestfactory.shared.ProxyFor; -//import com.google.web.bindery.requestfactory.shared.SkipInterfaceValidation; -// -//@ProxyFor(value = DnsZone.class) -//@SkipInterfaceValidation -//// @SkipInterfaceValidation as we rely on PlatformLayer ServiceLayerDecorator -//public interface DnsZoneProxy extends EntityProxy { -// // Boilerplate -// EntityProxyId stableId(); -// -// // Getters / Setters -// String getDnsName(); -// -// void setDnsName(String dnsName); -// -// static final Accessor DnsName = new Accessor() { -// @Override -// public String get(DnsZoneProxy o) { -// return o.getDnsName(); -// } -// -// @Override -// public void set(DnsZoneProxy o, String value) { -// o.setDnsName(value); -// } -// }; -// } diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/PlatformLayerRequestContext.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/PlatformLayerRequestContext.java deleted file mode 100644 index 4fdaa87d6..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/PlatformLayerRequestContext.java +++ /dev/null @@ -1,12 +0,0 @@ -//package org.platformlayer.ui.web.shared; -// -//import java.util.List; -// -//import com.google.web.bindery.requestfactory.shared.Request; -//import com.google.web.bindery.requestfactory.shared.RequestContext; -// -//public interface PlatformLayerRequestContext extends RequestContext { -// Request> findAll(Class proxyClass); -// -// Request persist(T proxy); -// } diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/PlatformLayerRequestFactory.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/PlatformLayerRequestFactory.java deleted file mode 100644 index d1eb7895d..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/PlatformLayerRequestFactory.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.platformlayer.ui.web.shared; - -import java.util.List; - -import org.platformlayer.service.aptcache.client.AptCacheProviderGwt; -import org.platformlayer.service.dns.client.DnsProviderGwt; -import org.platformlayer.service.dnsresolver.client.DnsResolverProviderGwt; -import org.platformlayer.service.openldap.client.LdapProviderGwt; -import org.platformlayer.ui.web.server.ServiceInfoService; -import org.platformlayer.ui.web.server.ServiceInfoServiceLocator; - -import com.google.web.bindery.requestfactory.shared.LoggingRequest; -import com.google.web.bindery.requestfactory.shared.Request; -import com.google.web.bindery.requestfactory.shared.RequestContext; -import com.google.web.bindery.requestfactory.shared.RequestFactory; -import com.google.web.bindery.requestfactory.shared.Service; - -public interface PlatformLayerRequestFactory extends LdapProviderGwt.ProviderRequestFactory, RequestFactory, DnsResolverProviderGwt.ProviderRequestFactory, DnsProviderGwt.ProviderRequestFactory, - AptCacheProviderGwt.ProviderRequestFactory { - @Service(value = ServiceInfoService.class, locator = ServiceInfoServiceLocator.class) - public interface ServiceInfoRequest extends RequestContext { - Request> findAll(); - } - - LoggingRequest loggingRequest(); - - // AptCacheServiceRequest aptCacheRequest(); - - ServiceInfoRequest serviceInfoRequest(); - - // DnsZoneRequest dnsZoneRequest(); - // - // DnsRecordRequest dnsRecordRequest(); - // - // DnsServerRequest dnsServerRequest(); - -} diff --git a/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/ServiceInfoProxy.java b/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/ServiceInfoProxy.java deleted file mode 100644 index ee185ada1..000000000 --- a/gui/web-main/src/main/java/org/platformlayer/ui/web/shared/ServiceInfoProxy.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2007 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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 org.platformlayer.ui.web.shared; - -import java.util.List; - -import org.platformlayer.core.model.ServiceInfo; -import org.platformlayer.ui.web.server.ServiceInfoLocator; - -import com.google.web.bindery.requestfactory.shared.EntityProxy; -import com.google.web.bindery.requestfactory.shared.EntityProxyId; -import com.google.web.bindery.requestfactory.shared.ProxyFor; - -/** - * Person DTO. - */ -@ProxyFor(value = ServiceInfo.class, locator = ServiceInfoLocator.class) -public interface ServiceInfoProxy extends EntityProxy { - // Boilerplate - EntityProxyId stableId(); - - // Getters / Setters - String getDescription(); - - String getServiceType(); - - List getPublicTypes(); - -} diff --git a/gui/web-main/src/main/webapp/PlatformLayerUi.html b/gui/web-main/src/main/webapp/PlatformLayerUi.html deleted file mode 100644 index 03a56128a..000000000 --- a/gui/web-main/src/main/webapp/PlatformLayerUi.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - DynaTable RequestFactory Example - - - - -

- Your web browser must have JavaScript enabled - in order for this application to display correctly. -
- - - diff --git a/gui/web-main/src/main/webapp/WEB-INF/deploy/platformlayerui/rpcPolicyManifest/manifest.txt b/gui/web-main/src/main/webapp/WEB-INF/deploy/platformlayerui/rpcPolicyManifest/manifest.txt deleted file mode 100644 index 137208480..000000000 --- a/gui/web-main/src/main/webapp/WEB-INF/deploy/platformlayerui/rpcPolicyManifest/manifest.txt +++ /dev/null @@ -1,2 +0,0 @@ -# Module platformlayerui -# RPC service class, partial path of RPC policy file diff --git a/gui/web-main/src/main/webapp/WEB-INF/web.xml b/gui/web-main/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index ea55a8494..000000000 --- a/gui/web-main/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - DynaTableRf.html - - - - - - - guiceFilter - com.google.inject.servlet.GuiceFilter - - - guiceFilter - /* - - - org.platformlayer.ui.web.server.GwtGuiceServletConfig - - - - diff --git a/gui/web-main/src/main/webapp/platformlayerui/clear.cache.gif b/gui/web-main/src/main/webapp/platformlayerui/clear.cache.gif deleted file mode 100644 index e565824aa..000000000 Binary files a/gui/web-main/src/main/webapp/platformlayerui/clear.cache.gif and /dev/null differ diff --git a/gui/web-main/src/main/webapp/platformlayerui/hosted.html b/gui/web-main/src/main/webapp/platformlayerui/hosted.html deleted file mode 100644 index f6c5d8232..000000000 --- a/gui/web-main/src/main/webapp/platformlayerui/hosted.html +++ /dev/null @@ -1,364 +0,0 @@ - - - -This html file is for Development Mode support. - diff --git a/gui/web-main/src/main/webapp/platformlayerui/platformlayerui.nocache.js b/gui/web-main/src/main/webapp/platformlayerui/platformlayerui.nocache.js deleted file mode 100644 index 2a5b2fca3..000000000 --- a/gui/web-main/src/main/webapp/platformlayerui/platformlayerui.nocache.js +++ /dev/null @@ -1,16 +0,0 @@ -function platformlayerui(){var N='',ub='" for "gwt:onLoadErrorFn"',sb='" for "gwt:onPropertyErrorFn"',gb='"><\/script>',X='#',Sb='.cache.html',Z='/',Rb=':',mb='::',Ub='