Permalink
Browse files

Initial implementation of the 'standalone' application type.

  • Loading branch information...
donovanmuller committed Oct 2, 2016
1 parent bd132de commit 64da383ce053abee5055bd8444305fca0c5c3dc5
Showing with 1,868 additions and 23 deletions.
  1. +6 −1 ...ng-cloud-dataflow-core/src/main/java/org/springframework/cloud/dataflow/core/ApplicationType.java
  2. +236 −0 ...oud-dataflow-core/src/main/java/org/springframework/cloud/dataflow/core/StandaloneDefinition.java
  3. +4 −2 spring-cloud-dataflow-core/src/main/java/org/springframework/cloud/dataflow/core/dsl/DSLMessage.java
  4. +75 −0 ...oud-dataflow-core/src/main/java/org/springframework/cloud/dataflow/core/dsl/StandaloneParser.java
  5. +6 −0 ...-rest-client/src/main/java/org/springframework/cloud/dataflow/rest/client/DataFlowOperations.java
  6. +17 −0 ...ow-rest-client/src/main/java/org/springframework/cloud/dataflow/rest/client/DataFlowTemplate.java
  7. +74 −0 ...est-client/src/main/java/org/springframework/cloud/dataflow/rest/client/StandaloneOperations.java
  8. +118 −0 ...-rest-client/src/main/java/org/springframework/cloud/dataflow/rest/client/StandaloneTemplate.java
  9. +105 −0 .../src/main/java/org/springframework/cloud/dataflow/rest/resource/StandaloneDefinitionResource.java
  10. +33 −0 .../src/main/java/org/springframework/cloud/dataflow/rest/resource/StandaloneDeploymentResource.java
  11. +33 −5 ...in/java/org/springframework/cloud/dataflow/server/config/DataFlowControllerAutoConfiguration.java
  12. +6 −6 ...rc/main/java/org/springframework/cloud/dataflow/server/config/features/FeaturesConfiguration.java
  13. +13 −0 ...e/src/main/java/org/springframework/cloud/dataflow/server/config/features/FeaturesProperties.java
  14. +39 −0 .../main/java/org/springframework/cloud/dataflow/server/config/features/StandaloneConfiguration.java
  15. +9 −0 ...erver-core/src/main/java/org/springframework/cloud/dataflow/server/controller/RootController.java
  16. +28 −9 ...ore/src/main/java/org/springframework/cloud/dataflow/server/controller/RuntimeAppsController.java
  17. +29 −0 ...java/org/springframework/cloud/dataflow/server/controller/StandaloneAlreadyDeployedException.java
  18. +29 −0 ...ava/org/springframework/cloud/dataflow/server/controller/StandaloneAlreadyDeployingException.java
  19. +278 −0 ...ain/java/org/springframework/cloud/dataflow/server/controller/StandaloneDefinitionController.java
  20. +326 −0 ...ain/java/org/springframework/cloud/dataflow/server/controller/StandaloneDeploymentController.java
  21. +29 −0 ...ain/java/org/springframework/cloud/dataflow/server/controller/StandaloneNotDeployedException.java
  22. +12 −0 ...server-core/src/main/java/org/springframework/cloud/dataflow/server/repository/DeploymentKey.java
  23. +35 −0 .../org/springframework/cloud/dataflow/server/repository/DuplicateStandaloneDefinitionException.java
  24. +41 −0 ...ava/org/springframework/cloud/dataflow/server/repository/NoSuchStandaloneDefinitionException.java
  25. +64 −0 ...ava/org/springframework/cloud/dataflow/server/repository/RdbmsStandaloneDefinitionRepository.java
  26. +29 −0 ...ain/java/org/springframework/cloud/dataflow/server/repository/StandaloneDefinitionRepository.java
  27. +9 −0 ...n/java/org/springframework/cloud/dataflow/server/repository/support/DataflowRdbmsInitializer.java
  28. +4 −0 spring-cloud-dataflow-server-core/src/main/resources/schema-h2-standalone.sql
  29. +181 −0 ...shell-core/src/main/java/org/springframework/cloud/dataflow/shell/command/StandaloneCommands.java
@@ -22,6 +22,7 @@
* @author Patrick Peralta
* @author Eric Bottard
* @author Mark Fisher
* @author Donovan Muller
*/
public enum ApplicationType {
@@ -43,6 +44,10 @@
/**
* An application type to execute a short-lived process.
*/
task;
task,
/**
* An application type to run standalone applications.
*/
standalone;
}
@@ -0,0 +1,236 @@
/*
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.dataflow.core;
import java.util.HashMap;
import java.util.Map;
import org.springframework.cloud.dataflow.core.dsl.AppNode;
import org.springframework.cloud.dataflow.core.dsl.ArgumentNode;
import org.springframework.cloud.dataflow.core.dsl.StandaloneParser;
import org.springframework.cloud.deployer.spi.core.AppDefinition;
import org.springframework.core.style.ToStringCreator;
/**
* Based on {@link TaskDefinition}
*
* @author Donovan Muller
*/
public class StandaloneDefinition extends DataFlowAppDefinition {
/**
* DSL text for the module.
*/
private final String dslText;
public StandaloneDefinition(String registeredAppName, String dsl) {
this.dslText = dsl;
AppNode standaloneNode = new StandaloneParser(registeredAppName, dsl).parse();
setRegisteredAppName(registeredAppName);
Map<String, String> properties = new HashMap<>();
if (standaloneNode.hasArguments()) {
for (ArgumentNode argumentNode : standaloneNode.getArguments()) {
properties.put(argumentNode.getName(), argumentNode.getValue());
}
}
this.appDefinition = new AppDefinition(standaloneNode.getName(), properties);
}
StandaloneDefinition(String registeredAppName, String label, Map<String, String> properties) {
super(registeredAppName, label, properties);
this.dslText = "";
}
public String getDslText() {
return dslText;
}
@Override
public String toString() {
return new ToStringCreator(this)
.append("dslText", this.dslText)
.append("appDefinition", this.appDefinition).toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((dslText == null) ? 0 : dslText.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
StandaloneDefinition other = (StandaloneDefinition) obj;
if (dslText == null) {
if (other.dslText != null)
return false;
} else if (!dslText.equals(other.dslText))
return false;
return true;
}
/**
* Builder object for {@code StandaloneDefinition}.
* This object is mutable to allow for flexibility in specifying application
* fields/properties during parsing.
*/
public static class Builder {
/**
* @see DataFlowAppDefinition#registeredAppName
*/
private String registeredAppName;
/**
* @see AppDefinition#getName()
*/
private String label;
/**
* @see AppDefinition#getProperties()
*/
private final Map<String, String> properties = new HashMap<String, String>();
/**
* Create a new builder that is initialized with properties of the given definition.
* Useful for "mutating" a definition by building a slightly different copy.
*/
public static Builder from(DataFlowAppDefinition definition) {
Builder builder = new Builder();
builder.setRegisteredAppName(definition.getRegisteredAppName())
.setLabel(definition.getName())
.addProperties(definition.getProperties());
return builder;
}
/**
* Set the name of the app in the registry.
*
* @param registeredAppName name of app in registry
* @return this builder object
*
* @see DataFlowAppDefinition#registeredAppName
*/
public Builder setRegisteredAppName(String registeredAppName) {
this.registeredAppName = registeredAppName;
return this;
}
/**
* Set the app label.
*
* @param label name of app label
* @return this builder object
*
* @see DataFlowAppDefinition#label
*/
public Builder setLabel(String label) {
this.label = label;
return this;
}
/**
* Set an app property.
*
* @param name property name
* @param value property value
* @return this builder object
*
* @see AppDefinition#getProperties()
*/
public Builder setProperty(String name, String value) {
this.properties.put(name, value);
return this;
}
/**
* Add the contents of the provided map to the map of app properties.
*
* @param properties app properties
* @return this builder object
*
* @see AppDefinition#getProperties()
*/
public Builder addProperties(Map<String, String> properties) {
this.properties.putAll(properties);
return this;
}
/**
* Return name of standalone app in registry.
*
* @return standalone app name in registry
*/
public String getRegisteredAppName() {
return registeredAppName;
}
/**
* Return symbolic name of a standalone application. If not provided, it will be the same as the standalone application name.
*
* @return app label
*/
public String getLabel() {
return label;
}
/**
* Return properties for the standalone application.
* Note that the contents of this map are <b>mutable</b>.
*
* @return map of app properties
*/
public Map<String, String> getProperties() {
return properties;
}
/**
* Sets standalone application properties.
*
* @param properties standalone application properties
* @return this builder object
*
* @see AppDefinition#getProperties()
*/
public StandaloneDefinition.Builder setProperties(Map<String, String> properties) {
this.properties.clear();
this.addProperties(properties);
return this;
}
/**
* Return a new instance of {@link StandaloneDefinition}.
*
* @return new instance of {@code StandaloneDefinition}
*/
public StandaloneDefinition build(String name) {
if (this.label == null) {
this.label = name;
}
return new StandaloneDefinition(this.registeredAppName, this.label, this.properties);
}
}
}
@@ -38,6 +38,7 @@
* @author Andy Clement
* @author Ilayaperumal Gopinathan
* @author Mark Fisher
* @author Donovan Muller
*/
public enum DSLMessage {
@@ -91,7 +92,8 @@
"no whitespace is allowed between dot and components of a name"),
DESTINATIONS_UNSUPPORTED_HERE(ERROR, 146, "a destination is not supported in this kind of definition"),
EXPECTED_WHITESPACE_AFTER_LABEL_COLON(ERROR, 147, "whitespace is expected after an app label"),
EXPECTED_STREAM_NAME_AFTER_LABEL_COLON(ERROR, 148, "stream name is expected after an app label")
EXPECTED_STREAM_NAME_AFTER_LABEL_COLON(ERROR, 148, "stream name is expected after an app label"),
ILLEGAL_STANDALONE_NAME(ERROR, 149, "illegal name for a standalone application ''{0}''"),
;
private Kind kind;
@@ -144,4 +146,4 @@ public Kind getKind() {
INFO, WARNING, ERROR
}
}
}
@@ -0,0 +1,75 @@
/*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.dataflow.core.dsl;
/**
* Parser for standalone DSL that generates {@link AppNode}.
*
* @author Donovan Muller
*/
public class StandaloneParser extends AppParser {
/**
* Standalone application name (may be {@code null}).
*/
private final String name;
/**
* Construct a {@code StandaloneParser} without supplying the standalone application name up front.
* The standalone application name may be embedded in the definition; for example:
* {@code myApp = app}
*
* @param dsl the standalone definition DSL text
*/
public StandaloneParser(String dsl) {
this(null, dsl);
}
/**
* Construct a {@code StandaloneParser} for a standalone application with the provided name.
*
* @param name standalone application name
* @param dsl standalone application dsl text
*/
public StandaloneParser(String name, String dsl) {
super(new Tokens(dsl));
this.name = name;
}
/**
* Parse a standalone application definition.
*
* @return the AST for the parsed standalone application
* @throws ParseException
*/
public AppNode parse() {
AppNode ast = eatApp();
if (ast.getName() != null && !isValidName(ast.getName())) {
throw new ParseException(ast.getName(), 0, DSLMessage.ILLEGAL_STANDALONE_NAME, ast.getName());
}
if (name != null && !isValidName(name)) {
throw new ParseException(name, 0, DSLMessage.ILLEGAL_STANDALONE_NAME, name);
}
Tokens tokens = getTokens();
if (tokens.hasNext()) {
tokens.raiseException(tokens.peek().startPos, DSLMessage.MORE_INPUT, toString(tokens.next()));
}
return ast;
}
}
@@ -22,9 +22,15 @@
* @author Ilayaperumal Gopinathan
* @author Glenn Renfro
* @author Mark Fisher
* @author Donovan Muller
*/
public interface DataFlowOperations {
/**
* Standalone application related operations.
*/
StandaloneOperations standaloneOperations();
/**
* Stream related operations.
*/
Oops, something went wrong.

0 comments on commit 64da383

Please sign in to comment.