/******************************************************************************* * Copyright (c) 2012-2014 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. - initial API and implementation ******************************************************************************/ package com.openshift.internal.client; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import com.openshift.client.IAuthorization; import com.openshift.client.IDomain; import com.openshift.client.IHttpClient; import com.openshift.client.IOpenShiftConnection; import com.openshift.client.IQuickstart; import com.openshift.client.IUser; import com.openshift.client.OpenShiftException; import com.openshift.client.cartridge.EmbeddableCartridge; import com.openshift.client.cartridge.ICartridge; import com.openshift.client.cartridge.IEmbeddableCartridge; import com.openshift.client.cartridge.IStandaloneCartridge; import com.openshift.client.cartridge.StandaloneCartridge; import com.openshift.internal.client.httpclient.request.Parameter; import com.openshift.internal.client.httpclient.request.StringParameter; import com.openshift.internal.client.response.AuthorizationResourceDTO; import com.openshift.internal.client.response.CartridgeResourceDTO; import com.openshift.internal.client.response.DomainResourceDTO; import com.openshift.internal.client.response.Link; import com.openshift.internal.client.response.QuickstartDTO; import com.openshift.internal.client.response.QuickstartJsonDTOFactory; import com.openshift.internal.client.response.UserResourceDTO; import com.openshift.internal.client.utils.Assert; import com.openshift.internal.client.utils.CollectionUtils; import com.openshift.internal.client.utils.IOpenShiftJsonConstants; /** * @author Andre Dietisheim * @author Xavier Coulon * @author Sean Kavanagh */ public class APIResource extends AbstractOpenShiftResource implements IOpenShiftConnection { private final String login; private final String password; // TODO: dont rely on a single token, we could have several authorizations // existing on the server private final String token; private UserResource user; private AuthorizationResource authorization; private List<IDomain> domains; private List<IStandaloneCartridge> standaloneCartridges; private List<IEmbeddableCartridge> embeddableCartridges; private List<IAuthorization> authorizations; private Map<String, IQuickstart> quickstartsByName; private final ExecutorService executorService; protected APIResource(final String token, final IRestService service, final Map<String, Link> links) { super(service, links, null); this.login = null; this.password = null; this.token = token; this.executorService = Executors.newFixedThreadPool(10); } protected APIResource(final String login, final String password, final String token, final IRestService service, final Map<String, Link> links) { super(service, links, null); this.login = login; this.password = password; this.token = token; this.executorService = Executors.newFixedThreadPool(10); } protected final String getLogin() { return login; } protected final String getPassword() { return password; } @Override public String getServer() { return getService().getPlatformUrl(); } @Override public IUser getUser() throws OpenShiftException { if (user == null) { this.user = new UserResource(this, new GetUserRequest().execute(), this.password); } return this.user; } public IAuthorization createAuthorization(String note, String scopes) throws OpenShiftException { return createAuthorization(note, scopes, null); } protected AuthorizationResource createAuthorization(String note, String scopes, Integer expiresIn) throws OpenShiftException { if (authorizations == null) { authorizations = loadAuthorizations(); } Parameters parameters = new Parameters() .add(IOpenShiftJsonConstants.PROPERTY_NOTE, note) .add(IOpenShiftJsonConstants.PROPERTY_SCOPES, scopes) .add(IOpenShiftJsonConstants.PROPERTY_EXPIRES_IN, expiresIn == null ? null : Integer.toString(expiresIn)); authorization = new AuthorizationResource(this, new AddAuthorizationRequest().execute(parameters.toArray())); // add to cached authorizations authorizations.add(authorization); return authorization; } protected void removeAuthorization() { this.authorization = null; } protected AuthorizationResource getOrCreateAuthorization(String token) { if (token == null) { return createAuthorization(null, IOpenShiftJsonConstants.PROPERTY_SESSION, IAuthorization.NO_EXPIRES_IN); } else { return new AuthorizationResource( this, new ShowAuthorizationRequest().execute(token)); } } public IAuthorization getAuthorization() throws OpenShiftException { if (authorization == null || authorization.getId() == null) { // TODO: if the given token is expired we get an exception here this.authorization = getOrCreateAuthorization(token); } return this.authorization; } public IAuthorization getAuthorization(String id) throws OpenShiftException { for (IAuthorization authorization : getAuthorizations()) { if (authorization.getId().equals(id) || authorization.getToken().equals(id)) { return authorization; } } return null; } public List<IAuthorization> getAuthorizations() throws OpenShiftException { if (authorizations == null) { this.authorizations = loadAuthorizations(); } return CollectionUtils.toUnmodifiableCopy(this.authorizations); } private List<IAuthorization> loadAuthorizations() throws OpenShiftException { List<IAuthorization> authorizations = new ArrayList<IAuthorization>(); for (AuthorizationResourceDTO authorizationDTO : new ListAuthorizationsRequest().execute()) { authorizations.add(new AuthorizationResource(this, authorizationDTO)); } return authorizations; } @Override public List<IDomain> getDomains() throws OpenShiftException { if (domains == null) { this.domains = loadDomains(); } return CollectionUtils.toUnmodifiableCopy(this.domains); } private List<IDomain> loadDomains() throws OpenShiftException { List<IDomain> domains = new ArrayList<IDomain>(); for (DomainResourceDTO domainDTO : new ListDomainsRequest().execute()) { domains.add(new DomainResource(domainDTO, this)); } return domains; } public IDomain getDomain(String id) throws OpenShiftException { Assert.notNull(id); for (IDomain domain : getDomains()) { if (domain.getId().equals(id)) { return domain; } } return null; } public IDomain getDefaultDomain() { final List<IDomain> domains = getDomains(); if (domains.size() > 0) { return domains.get(0); } return null; } public IDomain createDomain(String id) throws OpenShiftException { Assert.notNull(id); if (hasDomain(id)) { throw new OpenShiftException("Domain {0} already exists", id); } final DomainResourceDTO domainDTO = new AddDomainRequest().execute(id); final IDomain domain = new DomainResource(domainDTO, this); this.domains.add(domain); return domain; } public IDomain showDomain(String id) throws OpenShiftException { Assert.notNull(id); final DomainResourceDTO domainDTO = new ShowDomainRequest().execute(id); // TODO: implement caching return new DomainResource(domainDTO, this); } @Override public List<IStandaloneCartridge> getStandaloneCartridges() throws OpenShiftException { return getStandaloneCartridges(false); } @Override public List<IStandaloneCartridge> getStandaloneCartridges(boolean includeObsolete) throws OpenShiftException { return CollectionUtils.toUnmodifiableCopy(filterObsolete(includeObsolete, getOrLoadStandaloneCartridges())); } protected List<IStandaloneCartridge> getOrLoadStandaloneCartridges() throws OpenShiftException { if (standaloneCartridges == null) { loadCartridges(); } return standaloneCartridges; } @Override public List<IEmbeddableCartridge> getEmbeddableCartridges() throws OpenShiftException { return getEmbeddableCartridges(false); } @Override public List<IEmbeddableCartridge> getEmbeddableCartridges(boolean includeObsolete) throws OpenShiftException { return CollectionUtils.toUnmodifiableCopy(filterObsolete(includeObsolete, getOrLoadEmbeddableCartridges())); } protected List<IEmbeddableCartridge> getOrLoadEmbeddableCartridges() throws OpenShiftException { if (embeddableCartridges == null) { loadCartridges(); } return embeddableCartridges; } protected <C extends ICartridge> List<C> filterObsolete(boolean includeObsolete, List<C> allCartridges) { if (includeObsolete) { return allCartridges; } List<C> filteredList = new ArrayList<C>(allCartridges.size()); for (C cartridge : allCartridges) { if (!cartridge.isObsolete()) { filteredList.add(cartridge); } } return filteredList; } @Override public List<ICartridge> getCartridges() { return getCartridges(false); } @Override public List<ICartridge> getCartridges(boolean includeObsolete) { List<IEmbeddableCartridge> embeddableCartridges = getOrLoadEmbeddableCartridges(); List<IStandaloneCartridge> standaloneCartridges = getOrLoadStandaloneCartridges(); List<ICartridge> cartridges = new ArrayList<ICartridge>(embeddableCartridges.size() + standaloneCartridges.size()); cartridges.addAll(filterObsolete(includeObsolete, embeddableCartridges)); cartridges.addAll(filterObsolete(includeObsolete, standaloneCartridges)); return cartridges; } private void loadCartridges() throws OpenShiftException { final Map<String, CartridgeResourceDTO> cartridgeDTOsByName = new GetCartridgesRequest().execute(); this.standaloneCartridges = new ArrayList<IStandaloneCartridge>(); this.embeddableCartridges = new ArrayList<IEmbeddableCartridge>(); for (CartridgeResourceDTO cartridgeDTO : cartridgeDTOsByName.values()) { addCartridge(cartridgeDTO, standaloneCartridges, embeddableCartridges); } } private void addCartridge(CartridgeResourceDTO dto, List<IStandaloneCartridge> standaloneCartridges, List<IEmbeddableCartridge> embeddableCartridges) { switch (dto.getType()) { case STANDALONE: standaloneCartridges.add( new StandaloneCartridge(dto.getName(), dto.getDisplayName(), dto.getDescription(), dto .getObsolete())); break; case EMBEDDED: embeddableCartridges.add( new EmbeddableCartridge(dto.getName(), dto.getDisplayName(), dto.getDescription(), dto .getObsolete())); break; case UNDEFINED: break; } } @Override public void refresh() throws OpenShiftException { this.domains = null; this.authorizations = null; } /** * Called after a domain has been destroyed * * @param domain * the domain to remove from the API's domains list. */ protected void removeDomain(final IDomain domain) { this.domains.remove(domain); } protected boolean hasDomain(String name) throws OpenShiftException { return getDomain(name) != null; } public List<IQuickstart> getQuickstarts() { if (quickstartsByName == null) { this.quickstartsByName = loadQuickstarts(); } return CollectionUtils.toUnmodifiableCopy(this.quickstartsByName.values()); } private Map<String, IQuickstart> loadQuickstarts() throws OpenShiftException { Map<String, IQuickstart> quickstarts = new HashMap<String, IQuickstart>(); for (QuickstartDTO quickstartDTO : new ListQuickstartsRequest().execute()) { quickstarts.put(quickstartDTO.getName(), new Quickstart(quickstartDTO, this)); } return quickstarts; } public ExecutorService getExecutorService() { return executorService; } public void disconnect() { standaloneCartridges = null; embeddableCartridges = null; domains = null; executorService.shutdownNow(); } private class AddDomainRequest extends ServiceRequest { private AddDomainRequest() throws OpenShiftException { super("ADD_DOMAIN"); } private DomainResourceDTO execute(String namespace) throws OpenShiftException { return execute(new StringParameter(IOpenShiftJsonConstants.PROPERTY_ID, namespace)); } } private class ListDomainsRequest extends ServiceRequest { private ListDomainsRequest() throws OpenShiftException { super("LIST_DOMAINS"); } protected List<DomainResourceDTO> execute() throws OpenShiftException { return super.execute(); } } private class GetUserRequest extends ServiceRequest { private GetUserRequest() throws OpenShiftException { super("GET_USER"); } protected UserResourceDTO execute() throws OpenShiftException { return super.execute(); } } private class GetCartridgesRequest extends ServiceRequest { private GetCartridgesRequest() throws OpenShiftException { super("LIST_CARTRIDGES"); } protected Map<String, CartridgeResourceDTO> execute() throws OpenShiftException { return super.execute(); } } private class ShowDomainRequest extends ServiceRequest { private ShowDomainRequest() throws OpenShiftException { super("SHOW_DOMAIN"); } protected DomainResourceDTO execute(String id) throws OpenShiftException { List<Parameter> urlPathParameter = new Parameters().add("name", id).toList(); return super.execute(IHttpClient.NO_TIMEOUT, urlPathParameter, // url path parameter Collections.<Parameter> emptyList()); // request body // parameter } } private class ListQuickstartsRequest extends ServiceRequest { private ListQuickstartsRequest() throws OpenShiftException { super("LIST_QUICKSTARTS"); } protected List<QuickstartDTO> execute() throws OpenShiftException { return super.execute(IHttpClient.NO_TIMEOUT, new QuickstartJsonDTOFactory(), Collections.<Parameter> emptyList(), Collections.<Parameter> emptyList()); } } private class AddAuthorizationRequest extends ServiceRequest { private AddAuthorizationRequest() throws OpenShiftException { super("ADD_AUTHORIZATION"); } protected AuthorizationResourceDTO execute(Parameter... parameters) throws OpenShiftException { return super.execute(parameters); } } private class ShowAuthorizationRequest extends ServiceRequest { private ShowAuthorizationRequest() throws OpenShiftException { super("SHOW_AUTHORIZATION"); } protected AuthorizationResourceDTO execute(String id) throws OpenShiftException { List<Parameter> urlPathParameter = new Parameters().add("id", id).toList(); return (AuthorizationResourceDTO) super.execute(IHttpClient.NO_TIMEOUT, urlPathParameter, Collections.<Parameter> emptyList()); } } private class ListAuthorizationsRequest extends ServiceRequest { private ListAuthorizationsRequest() throws OpenShiftException { super("LIST_AUTHORIZATIONS"); } protected List<AuthorizationResourceDTO> execute() throws OpenShiftException { return super.execute(); } } }