Skip to content

Commit

Permalink
AppManager: Allow ReadWrite API Apps to install with ReadOnly (OpenEM…
Browse files Browse the repository at this point in the history
…S#1861)

ReadWrite API Apps can be installed with existing ReadOnly Apps. The ReadOnly Apps are getting disabled automatically installing an ReadWrite App and enabled when the ReadWrite App gets deinstalled.

Co-authored-by: Michael Grill <michael.grill@fenecon.de>
  • Loading branch information
michaelgrill and Michael Grill authored Jun 27, 2022
1 parent 8a49669 commit 44d66a0
Show file tree
Hide file tree
Showing 13 changed files with 379 additions and 198 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import io.openems.common.function.ThrowingTriFunction;
import io.openems.common.session.Language;
import io.openems.common.types.EdgeConfig;
import io.openems.common.utils.EnumUtils;
import io.openems.common.utils.JsonUtils;
import io.openems.edge.app.api.ModbusTcpApiReadOnly.Property;
import io.openems.edge.common.component.ComponentManager;
Expand All @@ -41,6 +42,7 @@
"instanceId": UUID,
"image": base64,
"properties":{
"ACTIVE": true,
"CONTROLLER_ID": "ctrlApiModbusTcp0"
},
"appDescriptor": {
Expand All @@ -54,7 +56,10 @@ public class ModbusTcpApiReadOnly extends AbstractOpenemsApp<Property> implement

public static enum Property {
// Components
CONTROLLER_ID;
CONTROLLER_ID, //
// Properties
ACTIVE, //
;
}

@Activate
Expand Down Expand Up @@ -88,6 +93,9 @@ public OpenemsAppCardinality getCardinality() {
@Override
protected ThrowingTriFunction<ConfigurationTarget, EnumMap<Property, JsonElement>, Language, AppConfiguration, OpenemsNamedException> appConfigurationFactory() {
return (t, p, l) -> {
if (!EnumUtils.getAsOptionalBoolean(p, Property.ACTIVE).orElse(true)) {
return new AppConfiguration();
}

var controllerId = this.getId(t, p, Property.CONTROLLER_ID, "ctrlApiModbusTcp0");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import java.util.EnumMap;
import java.util.List;
import java.util.TreeMap;

import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentContext;
Expand Down Expand Up @@ -33,8 +32,7 @@
import io.openems.edge.core.appmanager.OpenemsAppCardinality;
import io.openems.edge.core.appmanager.OpenemsAppCategory;
import io.openems.edge.core.appmanager.TranslationUtil;
import io.openems.edge.core.appmanager.validator.CheckAppsNotInstalled;
import io.openems.edge.core.appmanager.validator.ValidatorConfig;
import io.openems.edge.core.appmanager.dependency.DependencyDeclaration;

/**
* Describes a App for ReadWrite Modbus/TCP Api.
Expand All @@ -50,6 +48,12 @@
"API_TIMEOUT": 60,
"COMPONENT_IDS": ["_sum", ...]
},
"dependencies": [
{
"key": "READ_ONLY",
"instanceId": UUID
}
],
"appDescriptor": {
"websiteUrl": URL
}
Expand Down Expand Up @@ -141,20 +145,24 @@ protected ThrowingTriFunction<ConfigurationTarget, EnumMap<Property, JsonElement
.addProperty("apiTimeout", apiTimeout) //
.add("component.ids", controllerIds).build()));

return new AppConfiguration(components);
var dependencies = Lists.newArrayList(new DependencyDeclaration("READ_ONLY", //
DependencyDeclaration.CreatePolicy.NEVER, //
DependencyDeclaration.UpdatePolicy.ALWAYS, //
DependencyDeclaration.DeletePolicy.NEVER, //
DependencyDeclaration.DependencyUpdatePolicy.ALLOW_ONLY_UNCONFIGURED_PROPERTIES, //
DependencyDeclaration.DependencyDeletePolicy.ALLOWED, //
DependencyDeclaration.AppDependencyConfig.create() //
.setAppId("App.Api.ModbusTcp.ReadOnly") //
.setProperties(JsonUtils.buildJsonObject() //
.addProperty(ModbusTcpApiReadOnly.Property.ACTIVE.name(),
t == ConfigurationTarget.DELETE) //
.build())
.build()));

return new AppConfiguration(components, null, null, dependencies);
};
}

@Override
protected io.openems.edge.core.appmanager.validator.ValidatorConfig.Builder getValidateBuilder() {
return ValidatorConfig.create() //
.setInstallableCheckableConfigs(
Lists.newArrayList(new ValidatorConfig.CheckableConfig(CheckAppsNotInstalled.COMPONENT_NAME,
new ValidatorConfig.MapBuilder<>(new TreeMap<String, Object>()) //
.put("appIds", new String[] { "App.Api.ModbusTcp.ReadOnly" }) //
.build())));
}

@Override
protected Class<Property> getPropertyClass() {
return Property.class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import java.util.EnumMap;
import java.util.List;
import java.util.TreeMap;

import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentContext;
Expand All @@ -16,6 +15,7 @@
import io.openems.common.function.ThrowingTriFunction;
import io.openems.common.session.Language;
import io.openems.common.types.EdgeConfig;
import io.openems.common.utils.EnumUtils;
import io.openems.common.utils.JsonUtils;
import io.openems.edge.app.api.RestJsonApiReadOnly.Property;
import io.openems.edge.common.component.ComponentManager;
Expand All @@ -28,8 +28,6 @@
import io.openems.edge.core.appmanager.OpenemsApp;
import io.openems.edge.core.appmanager.OpenemsAppCardinality;
import io.openems.edge.core.appmanager.OpenemsAppCategory;
import io.openems.edge.core.appmanager.validator.CheckAppsNotInstalled;
import io.openems.edge.core.appmanager.validator.ValidatorConfig;

/**
* Describes a App for ReadOnly Rest JSON Api.
Expand All @@ -41,6 +39,7 @@
"instanceId": UUID,
"image": base64,
"properties":{
"ACTIVE": true,
"CONTROLLER_ID": "ctrlApiRest0"
},
"appDescriptor": {
Expand All @@ -54,7 +53,10 @@ public class RestJsonApiReadOnly extends AbstractOpenemsApp<Property> implements

public static enum Property {
// Components
CONTROLLER_ID;
CONTROLLER_ID, //
// Properties
ACTIVE, //
;
}

@Activate
Expand Down Expand Up @@ -88,6 +90,9 @@ public OpenemsAppCardinality getCardinality() {
@Override
protected ThrowingTriFunction<ConfigurationTarget, EnumMap<Property, JsonElement>, Language, AppConfiguration, OpenemsNamedException> appConfigurationFactory() {
return (t, p, l) -> {
if (!EnumUtils.getAsOptionalBoolean(p, Property.ACTIVE).orElse(true)) {
return new AppConfiguration();
}
var controllerId = this.getId(t, p, Property.CONTROLLER_ID, "ctrlApiRest0");

List<EdgeConfig.Component> components = Lists.newArrayList(//
Expand All @@ -99,16 +104,6 @@ protected ThrowingTriFunction<ConfigurationTarget, EnumMap<Property, JsonElement
};
}

@Override
public ValidatorConfig.Builder getValidateBuilder() {
return ValidatorConfig.create() //
.setInstallableCheckableConfigs(Lists.newArrayList(//
new ValidatorConfig.CheckableConfig(CheckAppsNotInstalled.COMPONENT_NAME,
new ValidatorConfig.MapBuilder<>(new TreeMap<String, Object>()) //
.put("appIds", new String[] { "App.Api.RestJson.ReadWrite" }) //
.build())));
}

@Override
protected Class<Property> getPropertyClass() {
return Property.class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import java.util.EnumMap;
import java.util.List;
import java.util.TreeMap;

import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentContext;
Expand Down Expand Up @@ -32,8 +31,7 @@
import io.openems.edge.core.appmanager.OpenemsAppCardinality;
import io.openems.edge.core.appmanager.OpenemsAppCategory;
import io.openems.edge.core.appmanager.TranslationUtil;
import io.openems.edge.core.appmanager.validator.CheckAppsNotInstalled;
import io.openems.edge.core.appmanager.validator.ValidatorConfig;
import io.openems.edge.core.appmanager.dependency.DependencyDeclaration;

/**
* Describes a App for ReadWrite Rest JSON Api.
Expand Down Expand Up @@ -117,20 +115,24 @@ protected ThrowingTriFunction<ConfigurationTarget, EnumMap<Property, JsonElement
.addProperty("apiTimeout", apiTimeout) //
.build()));

return new AppConfiguration(components);
var dependencies = Lists.newArrayList(new DependencyDeclaration("READ_ONLY", //
DependencyDeclaration.CreatePolicy.NEVER, //
DependencyDeclaration.UpdatePolicy.ALWAYS, //
DependencyDeclaration.DeletePolicy.NEVER, //
DependencyDeclaration.DependencyUpdatePolicy.ALLOW_ONLY_UNCONFIGURED_PROPERTIES, //
DependencyDeclaration.DependencyDeletePolicy.ALLOWED, //
DependencyDeclaration.AppDependencyConfig.create() //
.setAppId("App.Api.RestJson.ReadOnly") //
.setProperties(JsonUtils.buildJsonObject() //
.addProperty(ModbusTcpApiReadOnly.Property.ACTIVE.name(),
t == ConfigurationTarget.DELETE) //
.build())
.build()));

return new AppConfiguration(components, null, null, dependencies);
};
}

@Override
public ValidatorConfig.Builder getValidateBuilder() {
return ValidatorConfig.create() //
.setInstallableCheckableConfigs(Lists.newArrayList(//
new ValidatorConfig.CheckableConfig(CheckAppsNotInstalled.COMPONENT_NAME,
new ValidatorConfig.MapBuilder<>(new TreeMap<String, Object>()) //
.put("appIds", new String[] { "App.Api.RestJson.ReadOnly" }) //
.build())));
}

@Override
protected Class<Property> getPropertyClass() {
return Property.class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -779,10 +779,7 @@ public void updateHosts(User user, List<String> ips, List<String> oldIps) throws
@Override
public Optional<EdgeConfig.Component> getComponent(String id, String factoryId) {
var comp = this.componentManager.getEdgeConfig().getComponent(id);
if (comp.isEmpty()) {
return Optional.empty();
}
if (!comp.get().getFactoryId().equals(factoryId)) {
if (comp.isEmpty() || !comp.get().getFactoryId().equals(factoryId)) {
return Optional.empty();
}
return comp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ public InputBuilder setInputType(Type type) {
}

public InputBuilder setPlaceholder(String placeholder) {
if (placeholder != null && placeholder.isBlank()) {
if (placeholder != null && !placeholder.isBlank()) {
this.templateOptions.addProperty("placeholder", placeholder);
} else if (this.templateOptions.has("placeholder")) {
this.templateOptions.remove("placeholder");
Expand Down Expand Up @@ -653,7 +653,7 @@ private RepeatBuilder(DefaultEnum property) {
}

public RepeatBuilder setAddText(String addText) {
if (addText != null && addText.isBlank()) {
if (addText != null && !addText.isBlank()) {
this.templateOptions.addProperty("addText", addText);
} else if (this.templateOptions.has("addText")) {
this.templateOptions.remove("addText");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ public enum OpenemsAppCategory {
API("api"),

/**
* Category for test apps.
*
* Category for test apps.
*
* <p>
* NOTE: Do not use this category for normal apps!
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,12 @@ public UpdateValues updateApp(User user, OpenemsAppInstance oldInstance, JsonObj
*/
public UpdateValues deleteApp(User user, OpenemsAppInstance instance) throws OpenemsNamedException;

/**
* Only available during a call of one of the other methods.
*
* @return null if none of the other mehtods is currently running else the
* {@link TemporaryApps}
*/
public TemporaryApps getTemporaryApps();

}
Loading

0 comments on commit 44d66a0

Please sign in to comment.