Skip to content

Commit

Permalink
CODENVY-502 allow to create factories object by providing a pluggable…
Browse files Browse the repository at this point in the history
… mechanism based on url parameters

Change-Id: I0c9554ac6d767e110f9bc39c30e2fb2712ad413f
Signed-off-by: Florent BENOIT <fbenoit@codenvy.com>
  • Loading branch information
benoitf committed May 23, 2016
1 parent a5791d1 commit 12d3f2c
Show file tree
Hide file tree
Showing 8 changed files with 533 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;

/**
* Client for Factory service.
Expand All @@ -33,10 +34,9 @@ public interface FactoryServiceClient {
* factory ID to retrieve
* @param validate
* indicates whether or not factory should be validated by accept validator
* @param callback
* callback which return valid JSON object of factory or exception if occurred
* @return Factory through a Promise
*/
void getFactory(@NotNull String factoryId, boolean validate, @NotNull AsyncRequestCallback<Factory> callback);
Promise<Factory> getFactory(@NotNull String factoryId, boolean validate);

/**
* @param factoryId
Expand Down Expand Up @@ -101,4 +101,17 @@ public interface FactoryServiceClient {
* @return updated factory
*/
Promise<Factory> updateFactory(String id, Factory factory);


/**
* Resolve factory object based on user parameters
*
* @param factoryParameters
* map containing factory data parameters provided through URL
* @param validate
* indicates whether or not factory should be validated by accept validator
* @return Factory through a Promise
*/
Promise<Factory> resolveFactory(@NotNull Map<String, String> factoryParameters, boolean validate);

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import static org.eclipse.che.ide.MimeType.APPLICATION_JSON;
import static org.eclipse.che.ide.json.JsonHelper.toJson;
import static org.eclipse.che.ide.rest.HTTPHeader.ACCEPT;

/**
* Implementation of {@link FactoryServiceClient} service.
Expand All @@ -54,16 +59,22 @@ public FactoryServiceClientImpl(AsyncRequestFactory asyncRequestFactory,
}

/**
* {@inheritDoc}
* Get valid JSON factory object based on input factory ID
*
* @param factoryId
* factory ID to retrieve
* @param validate
* indicates whether or not factory should be validated by accept validator
* @return Factory through a Promise
*/
@Override
public void getFactory(@NotNull String factoryId, boolean validate, @NotNull AsyncRequestCallback<Factory> callback) {
public Promise<Factory> getFactory(@NotNull String factoryId, boolean validate) {
StringBuilder url = new StringBuilder(API_FACTORY_BASE_URL).append(factoryId);
if (validate) {
url.append("?").append("validate=true");
}
asyncRequestFactory.createGetRequest(url.toString()).header(HTTPHeader.ACCEPT, MimeType.APPLICATION_JSON)
.send(callback);
return asyncRequestFactory.createGetRequest(url.toString()).header(HTTPHeader.ACCEPT, MimeType.APPLICATION_JSON)
.send(unmarshallerFactory.newUnmarshaller(Factory.class));
}

/**
Expand Down Expand Up @@ -141,6 +152,30 @@ public Promise<Factory> updateFactory(String id, Factory factory) {
.send(unmarshallerFactory.newUnmarshaller(Factory.class));
}


/**
* Resolve factory object based on user parameters
*
* @param factoryParameters
* map containing factory data parameters provided through URL
* @param validate
* indicates whether or not factory should be validated by accept validator
* @return Factory through a Promise
*/
@Override
public Promise<Factory> resolveFactory(@NotNull final Map<String, String> factoryParameters, boolean validate) {

// Init string with JAX-RS path
StringBuilder url = new StringBuilder(API_FACTORY_BASE_URL + "resolver");

// If validation, needs to add the flag
if (validate) {
url.append("?validate=true");
}
return asyncRequestFactory.createPostRequest(url.toString(), toJson(factoryParameters)).header(ACCEPT, APPLICATION_JSON)
.send(unmarshallerFactory.newUnmarshaller(Factory.class));
}

/**
* Forms the query string from collection of query params
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,39 @@
import com.google.web.bindery.event.shared.EventBus;

import org.eclipse.che.api.core.model.workspace.WorkspaceStatus;
import org.eclipse.che.ide.api.factory.FactoryServiceClient;
import org.eclipse.che.api.factory.shared.dto.Factory;
import org.eclipse.che.ide.api.machine.MachineManager;
import org.eclipse.che.api.promises.client.Function;
import org.eclipse.che.api.promises.client.FunctionException;
import org.eclipse.che.api.promises.client.Operation;
import org.eclipse.che.api.promises.client.OperationException;
import org.eclipse.che.api.promises.client.Promise;
import org.eclipse.che.api.promises.client.PromiseError;
import org.eclipse.che.ide.api.workspace.WorkspaceServiceClient;
import org.eclipse.che.api.workspace.shared.dto.WorkspaceDto;
import org.eclipse.che.ide.CoreLocalizationConstant;
import org.eclipse.che.ide.actions.WorkspaceSnapshotCreator;
import org.eclipse.che.ide.api.app.AppContext;
import org.eclipse.che.ide.api.component.Component;
import org.eclipse.che.ide.api.dialogs.DialogFactory;
import org.eclipse.che.ide.api.factory.FactoryServiceClient;
import org.eclipse.che.ide.api.machine.MachineManager;
import org.eclipse.che.ide.api.notification.NotificationManager;
import org.eclipse.che.ide.api.preferences.PreferencesManager;
import org.eclipse.che.ide.api.workspace.WorkspaceServiceClient;
import org.eclipse.che.ide.collections.Jso;
import org.eclipse.che.ide.collections.js.JsoArray;
import org.eclipse.che.ide.context.BrowserQueryFieldRenderer;
import org.eclipse.che.ide.dto.DtoFactory;
import org.eclipse.che.ide.rest.AsyncRequestCallback;
import org.eclipse.che.ide.rest.DtoUnmarshallerFactory;
import org.eclipse.che.ide.api.dialogs.DialogFactory;
import org.eclipse.che.ide.ui.loaders.initialization.InitialLoadingInfo;
import org.eclipse.che.ide.ui.loaders.initialization.LoaderPresenter;
import org.eclipse.che.ide.util.loging.Log;
import org.eclipse.che.ide.websocket.MessageBusProvider;
import org.eclipse.che.ide.workspace.create.CreateWorkspacePresenter;
import org.eclipse.che.ide.workspace.start.StartWorkspacePresenter;

import java.util.HashMap;
import java.util.Map;

import static org.eclipse.che.api.core.model.workspace.WorkspaceStatus.RUNNING;
import static org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode.FLOAT_MODE;
import static org.eclipse.che.ide.api.notification.StatusNotification.Status.FAIL;
Expand All @@ -56,8 +62,8 @@
*/
@Singleton
public class FactoryWorkspaceComponent extends WorkspaceComponent implements Component {
private final FactoryServiceClient factoryServiceClient;
private String workspaceId;
private final FactoryServiceClient factoryServiceClient;
private String workspaceId;

@Inject
public FactoryWorkspaceComponent(WorkspaceServiceClient workspaceServiceClient,
Expand Down Expand Up @@ -101,27 +107,46 @@ public FactoryWorkspaceComponent(WorkspaceServiceClient workspaceServiceClient,
@Override
public void start(final Callback<Component, Exception> callback) {
this.callback = callback;
String factoryParams = browserQueryFieldRenderer.getParameterFromURLByName("factory");
Jso factoryParams = browserQueryFieldRenderer.getParameters();
JsoArray<String> keys = factoryParams.getKeys();
Map<String, String> factoryParameters = new HashMap<>();
// check all factory parameters
for (String key : keys.toList()) {
if (key.startsWith("factory-")) {
String value = factoryParams.getStringField(key);
factoryParameters.put(key.substring("factory-".length()), value);
}
}

// get workspace ID to use dedicated workspace for this factory
this.workspaceId = browserQueryFieldRenderer.getParameterFromURLByName("workspaceId");

factoryServiceClient.getFactory(factoryParams, true,
new AsyncRequestCallback<Factory>(dtoUnmarshallerFactory.newUnmarshaller(Factory.class)) {
@Override
protected void onSuccess(Factory result) {
appContext.setFactory(result);

// get workspace
tryStartWorkspace();
}

@Override
protected void onFailure(Throwable error) {
Log.error(FactoryWorkspaceComponent.class, "Unable to load Factory", error);
callback.onFailure(new Exception(error.getCause()));
}
});
Promise<Factory> factoryPromise;
// now search if it's a factory based on id or from parameters
if (factoryParameters.containsKey("id")) {
factoryPromise = factoryServiceClient.getFactory(factoryParameters.get("id"), true);
} else {
factoryPromise = factoryServiceClient.resolveFactory(factoryParameters, true);
}

Promise<Void> promise = factoryPromise.then(new Function<Factory, Void>() {
@Override
public Void apply(final Factory factory) throws FunctionException {
appContext.setFactory(factory);

// get workspace
tryStartWorkspace();

return null;
}
}).catchError(new Operation<PromiseError>() {
@Override
public void apply(PromiseError error) throws OperationException {
Log.error(FactoryWorkspaceComponent.class, "Unable to load Factory", error);
callback.onFailure(new Exception(error.getCause()));
}
});

}

@Override
Expand Down
8 changes: 8 additions & 0 deletions wsmaster/che-core-api-factory/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
Expand All @@ -49,6 +53,10 @@
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*******************************************************************************
* Copyright (c) 2012-2016 Codenvy, S.A.
* All rights reserved. This program and the accompanying materials
* are 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:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.api.factory.server;

import org.eclipse.che.api.core.BadRequestException;
import org.eclipse.che.api.factory.shared.dto.Factory;

import javax.validation.constraints.NotNull;
import java.util.Map;

/**
* Defines a resolver that will produce factories for some parameters
*
* @author Florent Benoit
*/
public interface FactoryParametersResolver {

/**
* Resolver acceptance based on the given parameters.
*
* @param factoryParameters
* map of parameters dedicated to factories
* @return true if it will be accepted by the resolver implementation or false if it is not accepted
*/
boolean accept(@NotNull Map<String, String> factoryParameters);

/**
* Create factory object based on provided parameters
*
* @param factoryParameters
* map containing factory data parameters provided through URL
* @throws BadRequestException
* when data are invalid
*/
Factory createFactory(@NotNull Map<String, String> factoryParameters) throws BadRequestException;


}
Loading

0 comments on commit 12d3f2c

Please sign in to comment.