Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow chePlugin preferences to be string, int or boolean type #14174

Merged
merged 21 commits into from
Aug 16, 2019
Merged
Show file tree
Hide file tree
Changes from 20 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
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.EnvImpl</class>
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl</class>
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.EndpointImpl</class>
<class>org.eclipse.che.api.workspace.server.devfile.SerializableConverter</class>

<class>org.eclipse.che.api.ssh.server.model.impl.SshPairImpl</class>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*/
package org.eclipse.che.api.core.model.workspace.devfile;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

Expand All @@ -32,7 +33,7 @@ public interface Component {
* Returns the preferences of the plugin. Example value of preference: {@code java.home:
* /home/user/jdk11}
*/
Map<String, String> getPreferences();
Map<String, Serializable> getPreferences();

/**
* For 'kubernetes' and 'openshift' components types, returns absolute or devfile-relative
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ public PersistTestModuleBuilder addEntityClasses(Class<?>... entityClasses) {
return this;
}

/** Adds another non-entity class (like attribute converters etc) to class list. */
public PersistTestModuleBuilder addClass(Class<?> entityClass) {
entityFqnSet.add(entityClass.getName());
return this;
}

/** Sets persistence unit custom property. */
public PersistTestModuleBuilder setProperty(String name, String value) {
if (name != null && value != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import com.google.inject.TypeLiteral;
import org.eclipse.che.account.spi.AccountImpl;
import org.eclipse.che.api.workspace.server.devfile.SerializableConverter;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
import org.eclipse.che.api.workspace.server.model.impl.MachineConfigImpl;
Expand Down Expand Up @@ -91,6 +92,7 @@ protected void configure() {
org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl.class)
.addEntityClass(
"org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl$Attribute")
.addClass(SerializableConverter.class)
.setExceptionHandler(H2ExceptionHandler.class)
.build());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.EnvImpl</class>
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl</class>
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.EndpointImpl</class>
<class>org.eclipse.che.api.workspace.server.devfile.SerializableConverter</class>

<class>org.eclipse.che.api.workspace.server.model.impl.CommandImpl</class>
<class>org.eclipse.che.workspace.infrastructure.docker.snapshot.MachineSourceImpl</class>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.EnvImpl</class>
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl</class>
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.EndpointImpl</class>
<class>org.eclipse.che.api.workspace.server.devfile.SerializableConverter</class>

<class>org.eclipse.che.api.workspace.server.model.impl.CommandImpl</class>
<class>org.eclipse.che.workspace.infrastructure.docker.snapshot.MachineSourceImpl</class>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.EnvImpl</class>
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl</class>
<class>org.eclipse.che.api.workspace.server.model.impl.devfile.EndpointImpl</class>
<class>org.eclipse.che.api.workspace.server.devfile.SerializableConverter</class>

<class>org.eclipse.che.api.workspace.server.model.impl.CommandImpl</class>
<class>org.eclipse.che.workspace.infrastructure.docker.snapshot.MachineSourceImpl</class>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.Collection;
import org.eclipse.che.account.spi.AccountImpl;
import org.eclipse.che.api.user.server.model.impl.UserImpl;
import org.eclipse.che.api.workspace.server.devfile.SerializableConverter;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
import org.eclipse.che.api.workspace.server.model.impl.MachineConfigImpl;
Expand Down Expand Up @@ -89,6 +90,7 @@ protected void configure() {
org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl.class)
.addEntityClass(
"org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl$Attribute")
.addClass(SerializableConverter.class)
.setExceptionHandler(H2ExceptionHandler.class)
.build());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.Collection;
import org.eclipse.che.account.spi.AccountImpl;
import org.eclipse.che.api.user.server.model.impl.UserImpl;
import org.eclipse.che.api.workspace.server.devfile.SerializableConverter;
import org.eclipse.che.api.workspace.server.jpa.JpaStackDao;
import org.eclipse.che.api.workspace.server.jpa.JpaWorkspaceDao;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
Expand Down Expand Up @@ -100,6 +101,7 @@ protected void configure() {
org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl.class)
.addEntityClass(
"org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl$Attribute")
.addClass(SerializableConverter.class)
.setExceptionHandler(H2ExceptionHandler.class)
.build());
bind(DBInitializer.class).asEagerSingleton();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.google.inject.TypeLiteral;
import org.eclipse.che.account.spi.AccountImpl;
import org.eclipse.che.api.user.server.model.impl.UserImpl;
import org.eclipse.che.api.workspace.server.devfile.SerializableConverter;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
import org.eclipse.che.api.workspace.server.model.impl.MachineConfigImpl;
Expand Down Expand Up @@ -92,6 +93,7 @@ protected void configure() {
org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl.class)
.addEntityClass(
"org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl$Attribute")
.addClass(SerializableConverter.class)
.setExceptionHandler(H2ExceptionHandler.class)
.build());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.eclipse.che.api.workspace.activity.JpaWorkspaceActivityDao;
import org.eclipse.che.api.workspace.activity.WorkspaceActivity;
import org.eclipse.che.api.workspace.activity.WorkspaceActivityDao;
import org.eclipse.che.api.workspace.server.devfile.SerializableConverter;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
import org.eclipse.che.api.workspace.server.model.impl.MachineConfigImpl;
Expand Down Expand Up @@ -86,6 +87,7 @@ protected void configure() {
org.eclipse.che.api.workspace.server.model.impl.devfile.VolumeImpl.class)
.addEntityClass(
"org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl$Attribute")
.addClass(SerializableConverter.class)
.setExceptionHandler(H2ExceptionHandler.class)
.build());
bind(DBInitializer.class).asEagerSingleton();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,6 @@ public final class Constants {
*/
public static final String SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE = "sidecar.%s.memory_limit";

/**
* Template for workspace config attribute key that stores plugin component preference. The first
* %s should be replaced with `pluginPublisher/pluginName` and the second one should be replaced
* with preference name. Example value: `plugin.redhat/java.preference.java.home`.
*/
public static final String PLUGIN_PREFERENCE_ATTR_TEMPLATE = "plugin.%s.preference.%s";
mshaposhnik marked this conversation as resolved.
Show resolved Hide resolved

/**
* Describes workspace runtimes which perform start/stop of this workspace. Should be set/read
* from {@link Workspace#getAttributes}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*/
package org.eclipse.che.api.workspace.shared.dto.devfile;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
Expand Down Expand Up @@ -49,11 +50,11 @@ public interface ComponentDto extends Component {
ComponentDto withRegistryUrl(String registryUrl);

@Override
Map<String, String> getPreferences();
Map<String, Serializable> getPreferences();

void setPreferences(Map<String, String> preferences);
void setPreferences(Map<String, Serializable> preferences);

ComponentDto withPreferences(Map<String, String> preferences);
ComponentDto withPreferences(Map<String, Serializable> preferences);

@Override
String getReference();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.workspace.server.devfile;

import static java.lang.String.format;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.che.api.core.model.workspace.devfile.Component;

/**
* Helps to deserialize multi-type preferences into {@link Component} as a {@code Map}.
*
* @author Max Shaposhnyk
*/
public class PreferencesDeserializer extends JsonDeserializer<Map<String, Serializable>> {
mshaposhnik marked this conversation as resolved.
Show resolved Hide resolved

@Override
public Map<String, Serializable> deserialize(JsonParser jsonParser, DeserializationContext ctxt)
throws IOException {
Map<String, Serializable> result = new HashMap<>();
jsonParser.nextToken();
while (!JsonToken.END_OBJECT.equals(jsonParser.getCurrentToken())) {
JsonToken currentToken = jsonParser.nextValue();
switch (currentToken) {
case VALUE_NUMBER_INT:
case VALUE_NUMBER_FLOAT:
result.put(jsonParser.getCurrentName(), jsonParser.getNumberValue());
break;
case VALUE_FALSE:
case VALUE_TRUE:
result.put(jsonParser.getCurrentName(), jsonParser.getValueAsBoolean());
break;
case VALUE_STRING:
result.put(jsonParser.getCurrentName(), jsonParser.getValueAsString());
break;
default:
throw new JsonParseException(
jsonParser,
format(
"Unexpected value of the preference with key '%s'.",
jsonParser.getCurrentName()));
}
jsonParser.nextToken();
}
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.workspace.server.devfile;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.io.Serializable;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import org.eclipse.che.api.core.model.workspace.devfile.Component;

/**
* Helps to store and read serializable values of the preferences map in {@link Component} to/from
* database.
*
* @author Max Shaposhnyk
*/
@Converter(autoApply = true)
public class SerializableConverter implements AttributeConverter<Serializable, String> {

private ObjectMapper objectMapper;

public SerializableConverter() {
this.objectMapper = new ObjectMapper();
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE);
}

@Override
public String convertToDatabaseColumn(Serializable value) {
try {
return objectMapper.writeValueAsString(value);
} catch (JsonProcessingException e) {
throw new RuntimeException("Unable to serialize preference value:" + e.getMessage(), e);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you find better exception? Just re-throw RuntimeException is not nice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which one? Interface didn't allow ckecked exc-s here...

}
}

@Override
public Serializable convertToEntityAttribute(String dbData) {
try {
return objectMapper.readValue(dbData, Serializable.class);
} catch (IOException e) {
throw new RuntimeException("Unable to deserialize preference value:" + e.getMessage(), e);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here with RuntimeException

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@
import static org.eclipse.che.api.workspace.server.devfile.Constants.COMPONENT_ALIAS_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGIN_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.shared.Constants.PLUGIN_PREFERENCE_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_PLUGINS_ATTRIBUTE;

import java.util.Map.Entry;
import javax.inject.Inject;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
Expand Down Expand Up @@ -99,15 +97,6 @@ public void apply(
.put(format(SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE, fqn.getPublisherAndName()), memoryLimit);
}

for (Entry<String, String> preference : pluginComponent.getPreferences().entrySet()) {
workspaceConfig
.getAttributes()
.put(
format(
PLUGIN_PREFERENCE_ATTR_TEMPLATE, fqn.getPublisherAndName(), preference.getKey()),
mshaposhnik marked this conversation as resolved.
Show resolved Hide resolved
preference.getValue());
}

for (CommandImpl command : workspaceConfig.getCommands()) {
String commandComponent = command.getAttributes().get(COMPONENT_ALIAS_COMMAND_ATTRIBUTE);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

import static java.util.stream.Collectors.toCollection;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand All @@ -21,6 +23,7 @@
import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
Expand All @@ -35,6 +38,8 @@
import org.eclipse.che.api.core.model.workspace.devfile.Entrypoint;
import org.eclipse.che.api.core.model.workspace.devfile.Env;
import org.eclipse.che.api.core.model.workspace.devfile.Volume;
import org.eclipse.che.api.workspace.server.devfile.PreferencesDeserializer;
import org.eclipse.che.api.workspace.server.devfile.SerializableConverter;

/** @author Sergii Leshchenko */
@Entity(name = "DevfileComponent")
Expand All @@ -54,8 +59,10 @@ public class ComponentImpl implements Component {
name = "devfile_component_preferences",
joinColumns = @JoinColumn(name = "devfile_component_id"))
@MapKeyColumn(name = "preference_key")
@Convert(converter = SerializableConverter.class)
@Column(name = "preference")
private Map<String, String> preferences;
@JsonDeserialize(using = PreferencesDeserializer.class)
private Map<String, Serializable> preferences;

@Column(name = "alias")
private String alias;
Expand Down Expand Up @@ -190,7 +197,7 @@ public ComponentImpl(
String type,
String alias,
String id,
Map<String, String> preferences,
Map<String, Serializable> preferences,
String registryUrl,
String reference,
String referenceContent,
Expand Down Expand Up @@ -294,14 +301,14 @@ public void setRegistryUrl(String registryUrl) {
this.registryUrl = registryUrl;
}

public Map<String, String> getPreferences() {
public Map<String, Serializable> getPreferences() {
if (preferences == null) {
preferences = new HashMap<>();
}
return preferences;
}

public void setPreferences(Map<String, String> preferences) {
public void setPreferences(Map<String, Serializable> preferences) {
this.preferences = preferences;
}

Expand Down
Loading