Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/main/java/com/openshift3/client/ResourceKind.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,4 @@ public enum ResourceKind {
public String pluralize() {
return plural;
}

}
27 changes: 27 additions & 0 deletions src/main/java/com/openshift3/internal/client/APIModelVersion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc.
* All rights reserved. This program is made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors: Red Hat, Inc.
******************************************************************************/
package com.openshift3.internal.client;

import java.util.Comparator;

public interface APIModelVersion {

int getOrder();

static class VersionComparitor implements Comparator<APIModelVersion> {
@Override
public int compare(APIModelVersion v1, APIModelVersion v2) {
if(v2 == null) return 1;
if(v1 == null) return -1;
if(v1.getOrder() < v2.getOrder()) return -1;
if(v1.getOrder() > v2.getOrder()) return 1;
return 0;
}
};
}
105 changes: 83 additions & 22 deletions src/main/java/com/openshift3/internal/client/DefaultClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
******************************************************************************/
package com.openshift3.internal.client;

import static com.openshift3.client.capability.CapabilityInitializer.initializeCapability;;
import static com.openshift3.client.capability.CapabilityInitializer.initializeCapability;

import java.net.SocketTimeoutException;
import java.net.URL;
Expand All @@ -17,6 +17,7 @@
import java.util.List;
import java.util.Map;

import org.jboss.dmr.ModelNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -30,6 +31,7 @@
import com.openshift3.client.capability.server.IImageRegistryHosting;
import com.openshift3.client.model.IResource;
import com.openshift3.internal.client.capability.server.DefaultImageRegistryHosting;
import com.openshift3.internal.client.model.ResourcePropertiesRegistry;
import com.openshift3.internal.client.model.Status;

public class DefaultClient implements IClient{
Expand All @@ -41,24 +43,13 @@ public class DefaultClient implements IClient{
private Map<Class<? extends ICapability>, ICapability> capabilities = new HashMap<Class<? extends ICapability>, ICapability>();
private boolean capabilitiesInitialized = false;

private static final String apiEndpoint = "api/v1beta1";
private static final String osApiEndpoint = "osapi/v1beta1";
private static final String apiEndpoint = "api";
private static final String osApiEndpoint = "osapi";

private static final Map<ResourceKind, String> TYPE_MAPPING = new HashMap<ResourceKind, String>();
private final Map<ResourceKind, String> typeMappings = new HashMap<ResourceKind, String>();
private OpenShiftAPIVersion openShiftVersion;
private KubernetesAPIVersion kubernetesVersion;

static {
//OpenShift endpoints
TYPE_MAPPING.put(ResourceKind.BuildConfig, osApiEndpoint);
TYPE_MAPPING.put(ResourceKind.DeploymentConfig, osApiEndpoint);
TYPE_MAPPING.put(ResourceKind.ImageRepository, osApiEndpoint);
TYPE_MAPPING.put(ResourceKind.Project, osApiEndpoint);

//Kubernetes endpoints
TYPE_MAPPING.put(ResourceKind.Pod, apiEndpoint);
TYPE_MAPPING.put(ResourceKind.Service, apiEndpoint);

}

public DefaultClient(URL baseUrl){
this(baseUrl, null);
}
Expand Down Expand Up @@ -94,10 +85,10 @@ public <T extends IResource> List<T> list(ResourceKind kind, String namespace) {
@SuppressWarnings("unchecked")
@Override
public <T extends IResource> List<T> list(ResourceKind kind, String namespace, Map<String, String> labels) {
if(!TYPE_MAPPING.containsKey(kind))
if(!getTypeMappings().containsKey(kind))
throw new RuntimeException("No OpenShift resource endpoint for type: " + kind);
try {
URLBuilder builder = new URLBuilder(this.baseUrl, TYPE_MAPPING)
URLBuilder builder = new URLBuilder(this.baseUrl, getTypeMappings())
.kind(kind)
.namespace(namespace);
final URL endpoint = builder.build();
Expand Down Expand Up @@ -127,7 +118,7 @@ private <T extends IResource> List<T> filterItems(List<T> items, Map<String, Str
@Override
public <T extends IResource> T create(T resource) {
try {
final URL endpoint = new URLBuilder(this.baseUrl, TYPE_MAPPING)
final URL endpoint = new URLBuilder(this.baseUrl, getTypeMappings())
.kind(resource.getKind())
.addParmeter("namespace", resource.getNamespace())
.build();
Expand All @@ -145,10 +136,11 @@ public <T extends IResource> T create(T resource) {
@Override
public <T extends IResource> void delete(T resource) {
try {
final URL endpoint = new URLBuilder(this.baseUrl, TYPE_MAPPING)
final URL endpoint = new URLBuilder(this.baseUrl, getTypeMappings())
.resource(resource)
.addParmeter("namespace", resource.getNamespace())
.build();
LOGGER.debug(String.format("Deleting resource: %s", endpoint));
String response = client.delete(endpoint, IHttpClient.DEFAULT_READ_TIMEOUT);
LOGGER.debug(response);
//TODO return response object here
Expand All @@ -163,7 +155,7 @@ public <T extends IResource> void delete(T resource) {
@Override
public <T extends IResource> T get(ResourceKind kind, String name, String namespace) {
try {
final URL endpoint = new URLBuilder(this.baseUrl, TYPE_MAPPING)
final URL endpoint = new URLBuilder(this.baseUrl, getTypeMappings())
.kind(kind)
.name(name)
.addParmeter("namespace", namespace)
Expand Down Expand Up @@ -212,6 +204,75 @@ public boolean supports(Class<? extends ICapability> capability) {
return capabilities.containsKey(capability);
}

public List<KubernetesAPIVersion> getKubernetesVersions() {
return getVersion(KubernetesAPIVersion.class, apiEndpoint);
}

public List<OpenShiftAPIVersion> getOpenShiftVersions() {
return getVersion(OpenShiftAPIVersion.class, osApiEndpoint);
}

public KubernetesAPIVersion getKubernetesVersion() {
if(kubernetesVersion == null){
List<KubernetesAPIVersion> versions = getKubernetesVersions();
kubernetesVersion = ResourcePropertiesRegistry.getInstance().getMaxSupportedKubernetesVersion();
if(!versions.contains(kubernetesVersion)){
throw new RuntimeException(String.format("Kubernetes API version '%s' is not supported by this client"));
}
}
return kubernetesVersion;
}

public OpenShiftAPIVersion getOpenShiftVersion() {
if(openShiftVersion == null){
List<OpenShiftAPIVersion> versions = getOpenShiftVersions();
openShiftVersion = ResourcePropertiesRegistry.getInstance().getMaxSupportedOpenShiftVersion();
if(!versions.contains(openShiftVersion)){
throw new RuntimeException(String.format("OpenShift API version '%s' is not supported by this client"));
}
}
return openShiftVersion;
}

private <T extends Enum<T>> List<T> getVersion(Class<T> klass, String endpoint) {
try {
final URL url = new URL(this.baseUrl, endpoint);
LOGGER.debug(url.toString());
String response = client.get(url, IHttpClient.DEFAULT_READ_TIMEOUT);
LOGGER.debug(response);
ModelNode json = ModelNode.fromJSONString(response);
List<ModelNode> versionNodes = json.get("versions").asList();
List<T> versions = new ArrayList<T>(versionNodes.size());
for (ModelNode node : versionNodes) {
try{
versions.add(Enum.valueOf(klass, node.asString()));
}catch(IllegalArgumentException e){
LOGGER.warn(String.format("Unsupported server version '%s' for '%s'", node.asString(), klass.getSimpleName()));
}
}
return versions;
} catch (Exception e) {
LOGGER.error("Exception", e);
throw new RuntimeException(e);
}
}

private Map<ResourceKind, String> getTypeMappings(){
if(typeMappings.isEmpty()){
//OpenShift endpoints
final String osEndpoint = String.format("%s/%s", osApiEndpoint, getOpenShiftVersion());
typeMappings.put(ResourceKind.BuildConfig, osEndpoint);
typeMappings.put(ResourceKind.DeploymentConfig, osEndpoint);
typeMappings.put(ResourceKind.ImageRepository, osEndpoint);
typeMappings.put(ResourceKind.Project, osEndpoint);

//Kubernetes endpoints
final String k8eEndpoint = String.format("%s/%s", apiEndpoint, getKubernetesVersion());
typeMappings.put(ResourceKind.Pod, k8eEndpoint);
typeMappings.put(ResourceKind.Service, k8eEndpoint);
}
return typeMappings;
}


}
10 changes: 10 additions & 0 deletions src/main/java/com/openshift3/internal/client/IResourceFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,14 @@ public interface IResourceFactory {
* @return
*/
<T extends IResource> T create(String response) ;

/**
* Create a resource for a given version and kind
* @param version
* @param kind
* @return
*/
<T extends IResource> T create(String version, ResourceKind kind);


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc.
* All rights reserved. This program is made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors: Red Hat, Inc.
******************************************************************************/
package com.openshift3.internal.client;




/**
* This list of supported Kubernetes API Models
* by this client
*/
public enum KubernetesAPIVersion implements APIModelVersion{
v1beta1(1);

private int order;

KubernetesAPIVersion( int order){
this.order = order;
}

@Override
public int getOrder(){
return order;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*******************************************************************************
* Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc.
* All rights reserved. This program is made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors: Red Hat, Inc.
******************************************************************************/
package com.openshift3.internal.client;




/**
* This list of supported OpenShift API Models
* by this client
*/
public enum OpenShiftAPIVersion implements APIModelVersion{
v1beta1(1);

private int order;
OpenShiftAPIVersion(int order){
this.order = order;
}

@Override
public int getOrder(){
return order;
}
}
44 changes: 30 additions & 14 deletions src/main/java/com/openshift3/internal/client/ResourceFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
import com.openshift3.internal.client.model.BuildConfig;
import com.openshift3.internal.client.model.DeploymentConfig;
import com.openshift3.internal.client.model.ImageRepository;
import com.openshift3.internal.client.model.KubernetesResource;
import com.openshift3.internal.client.model.Pod;
import com.openshift3.internal.client.model.Project;
import com.openshift3.internal.client.model.ReplicationController;
import com.openshift3.internal.client.model.ResourcePropertiesRegistry;
import com.openshift3.internal.client.model.Service;
import com.openshift3.internal.client.model.Status;

Expand All @@ -35,6 +35,8 @@
*/
public class ResourceFactory implements IResourceFactory{

private static final String KIND = "kind";
private static final String APIVERSION = "apiVersion";
private static final Map<ResourceKind, Class<? extends IResource>> IMPL_MAP = new HashMap<ResourceKind, Class<? extends IResource>>();
static {
IMPL_MAP.put(ResourceKind.BuildConfig, BuildConfig.class);
Expand All @@ -54,16 +56,17 @@ public ResourceFactory(IClient client) {

public List<IResource> createList(String json, ResourceKind kind){
ModelNode data = ModelNode.fromJSONString(json);
String dataKind = data.get("kind").asString();
final String dataKind = data.get(KIND).asString();
if(ResourceKind.Project.toString().equals(dataKind)){
return buildProjectListForSingleProject(data);
return buildProjectListForSingleProject(json);
}
if(!(kind.toString() + "List").equals(dataKind)){
throw new RuntimeException(String.format("Unexpected container type '%s' for desired kind: %s", dataKind, kind));
}

try{
return buildList(data.get("items").asList(), IMPL_MAP.get(kind));
final String version = data.get(APIVERSION).asString();
return buildList(version, data.get("items").asList(), kind);
}catch(Exception e){
throw new RuntimeException(e);
}
Expand All @@ -73,30 +76,43 @@ public List<IResource> createList(String json, ResourceKind kind){
* Project is apparently special as query for project with namespace returns a singular
* project
*/
private List<IResource> buildProjectListForSingleProject(ModelNode data) {
private List<IResource> buildProjectListForSingleProject(String data) {
ArrayList<IResource> projects = new ArrayList<IResource>(1);
projects.add(new Project(data, client));
projects.add(create(data));
return projects;
}

private <T extends IResource> List<IResource> buildList(List<ModelNode> items, Class<T> kind) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Constructor<T> constructor = kind.getConstructor(ModelNode.class, IClient.class);
private List<IResource> buildList(final String version, List<ModelNode> items, ResourceKind kind) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
List<IResource> resources = new ArrayList<IResource>(items.size());
for (ModelNode item : items) {
resources.add(constructor.newInstance(item, client));
resources.add(create(item, version, kind));
}
return resources;
}

@SuppressWarnings("unchecked")
public <T extends IResource> T create(String response) {
KubernetesResource resource = new KubernetesResource(response);
ModelNode node = ModelNode.fromJSONString(response);
String version = node.get(APIVERSION).asString();
ResourceKind kind = ResourceKind.valueOf(node.get(KIND).asString());
return create(node, version, kind);
}

public <T extends IResource> T create(String version, ResourceKind kind) {
ModelNode node = new ModelNode();
node.get(APIVERSION).set(version);
node.get(KIND).set(kind.toString());
return create(node, version, kind);
}

@SuppressWarnings("unchecked")
private <T extends IResource> T create(ModelNode node, String version, ResourceKind kind) {
try {
Constructor<? extends IResource> constructor = IMPL_MAP.get(resource.getKind()).getConstructor(ModelNode.class, IClient.class);
return (T) constructor.newInstance(resource.getNode(), client);
Map<String, String[]> properyKeyMap = ResourcePropertiesRegistry.getInstance().get(version, kind);
Constructor<? extends IResource> constructor = IMPL_MAP.get(kind).getConstructor(ModelNode.class, IClient.class, Map.class);
return (T) constructor.newInstance(node, client, properyKeyMap);
} catch (Exception e) {
throw new RuntimeException(e);
}

}

}
Loading