Funcatron plays well with Spring Boot.
Follow these steps to wrap your Spring Boot app as a Funcatron app. Funcatron currently works with Spring Boot 1.4.x.
-
Make sure you annotate you
Application
class (the main entrypoint) with@EnableSwagger2
. -
Include a file like
FuncatronBridge.java
that tell Funcatron where to find things.import funcatron.service.spring_boot.SpringBootWrapper;
/** * Bridges Spring to Funcation. You must include a file like this in your project as * Spring's maven packaging doesn't pick up the services from included projects. */
public class FuncatronBridge extends SpringBootWrapper {
public FuncatronBridge() { super(); }
@Override public Class<?>[] classList() { return new Class<?>[]{Application.class}; } }
-
Include a file like
MyMockServer.java
that mocks the HTTP serverimport funcatron.service.spring_boot.MockServer; import org.springframework.stereotype.Component;
/** * Register our own mock server. Once again, necessary to mock requests */ @Component public class MyMockServer extends MockServer { }
-
Include the following dependencies in your pom.xml file:
<dependency> <groupId>funcatron</groupId> <artifactId>intf</artifactId> <version>0.3.0-SNAPSHOT</version> </dependency>
<dependency> <groupId>funcatron</groupId> <artifactId>spring_boot</artifactId> <version>0.3.0-SNAPSHOT</version> </dependency>
<dependency> <groupId>funcatron</groupId> <artifactId>devshim</artifactId> <version>0.3.0-SNAPSHOT</version> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>1.4.3.RELEASE</version> </dependency>
-
Include the following repositories in your pom.xml file:
<repository> <id>snapshots-repo</id> <url>https://oss.sonatype.org/content/repositories/snapshots</url> <releases><enabled>false</enabled></releases> <snapshots><enabled>true</enabled></snapshots> </repository>
-
Add the following to your pom.xml’s
<plugins>
section:<plugin> <groupId>eu.somatik.serviceloader-maven-plugin</groupId> <artifactId>serviceloader-maven-plugin</artifactId> <version>1.0.7</version> <configuration> <services> <param>funcatron.intf.ClassloaderProvider</param> <param>funcatron.intf.OperationProvider</param> </services> </configuration> <executions> <execution> <goals> <goal>generate</goal> </goals> </execution> </executions> </plugin>
<plugin> <groupId>org.codehaus.gmaven</groupId> <artifactId>gmaven-plugin</artifactId> <version>1.5</version> <executions> <execution> <phase>validate</phase> <goals> <goal>execute</goal> </goals> <configuration> <providerSelection>2.0</providerSelection> <properties> <script>git rev-parse HEAD</script> </properties> <source> def command = project.properties.script def process = command.execute() process.waitFor() def describe = process.in.text.trim() project.properties.setProperty('gitVersion',describe) </source> </configuration> </execution> </executions> </plugin>
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.1</version> <configuration> <archive> <manifest> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> </manifest> <manifestEntries> <GitHeadRev>${gitVersion}</GitHeadRev> </manifestEntries> </archive> </configuration> </plugin>
</plugins>
That’s about it. Funcatron should find and dispatch requests properly with this information.
So… here’s how to run the app devmode
What’s “devmode”? It’s the development-time connection between your running app (which can be running in your IDE and have breakpoints) and a very slimmed down Funcatron HTTP front-end. Doing super-fast turn-around (compile and go or even live development) is simple with “devshim”.
You have to do two things… fire up a “devmode” version of Funcatron and Register
your app with the
local, not clustered, version of Funcation.
Add this to your Spring Boot app… you start the Spring Boot app normally, then create a Funcatron “Context”,
get the Swagger information, and then Register
with the “devmode” Funcatron instance.
/**
* Just a plain old Spring app... but make sure you include the {@code @EnableSwagger2}
* annotation to hook up SpringFox and generate Swagger
*/
@SpringBootApplication
@EnableSwagger2
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication sa = new SpringApplication(Application.class);
sa.run(args);
// Now that we've got the app running... start the whole funcatron stuff
ContextImpl.initContext(new HashMap<>(),
Application.class.getClassLoader(),
Logger.getAnonymousLogger());
// Using SpringFox, get the Swagger
Map swagger = ContextImpl.runOperation(Constants.GetSwaggerConst,
new HashMap<>(),
Logger.getAnonymousLogger(), Map.class);
// write it to a temp file
File tmpFile = File.createTempFile("funcatron_swagger_", ".txt");
tmpFile.createNewFile();
FileOutputStream fos = new FileOutputStream(tmpFile);
fos.write(swagger.get("swagger").toString().getBytes("UTF-8"));
fos.flush();
fos.close();
// delete the temp file on exit
tmpFile.deleteOnExit();
// register with the devshim
Register.register(tmpFile);
}
}
Next, fire up a “devmode” Funcatron instance with:
docker run -ti --rm -e TRON_1=--devmode -p 3001:3001 -p 54657:54657 funcatron/tron:latest
When you run your app and call the Register.register(…)
method, your app will connect to the Funcatron
instance and you’ll be able to make http
requests on http://localhost:3001/
. Those requests will
be forwarded to your app. If you run your app in debug mode in your IDE, you can set breakpoints in
your running app and see what’s going on.