As usal the spring boot guys implement this feature.
The target deployment
The access url
This product product has multiple instance on the same tomcat deployed on different context root.Just changing the war name like this
${context_root_name}#myWarName.war
The application setup
- change log target
- many product instance means many RDBMS instances to (in our case) we have to change properties files
Few words on product
This product is built on micro services architecture approach. A big word to tell that we want to define many small and independant services :- independant means with their own execution context and data managment
- interoperability relying on "neutral/pivot" data exchange format (JSON) and communication API (HTTP) : Here we uses spring REST (hateos).
- jenkins (REST API)
- a wiki (manly consumer)
- maven (client API)
- a configuration server API for register and provide communication end point for each participant
Hateoas and data storage with spring
More than rewrite Spring tutorial, I give you the pointers Building REST services with Spring, andAccessing JPA Data with REST
Protect deployment behavior
We don't have a lot of time to automate the deployment yet. Whe could do that in the near future with ansible, fabric, salt or simply simple script because we don't have full admin rights on this machine. I have also in mind to see if we could use Karaf with many servlet container instances.Anyway, at the begining we choose to product safe war (that are no able to connect to RDBMS) deploy manually . We have only two environements to deploy and they are not really enough stable to spend time in automation now) To does that whe add the following in maven pom to remove the propertie file that sets up the application :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>package</id>
<phase>package</phase>
<configuration>
<target>
<unzip
src="target/${project.artifactId}-${project.version}
.${project.packaging}"
dest="target/excludeProps/" />
<delete
file="target/excludeProps/WEB-INF/classes/
application.properties" />
<delete file="target/excludeProps/WEB-INF/
classes/logback.xml" />
<zip
destfile="target/${project.artifactId}-
${project.version}_SAFE.${project.packaging}"
basedir="target/excludeProps" encoding="UTF-8" />
<delete dir="target/excludeProps" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Build the war
first I used the 58.2 spring boot doc... but no chance, nothing work.Then after googling I add spring-webmvc to make things work properly and then it works
<dependency>
<groupid>org.springframework</groupid>
<artifactid>spring-webmvc</artifactid>
</dependency>
provide test resources
How does I test rest and controller ?One solution is to use Spring test Stack :
- @RunWith(SpringJUnit4ClassRunner.class) and @SpringApplicationConfiguration(classes =...) This uses the custom extension of BlockJUnit4ClassRunner which provides functionality of the Spring TestContext
- @WebIntegrationTest({ "server.port=0", "management.port=0" }) wich provide a complete startup of application (http listening on port)
- @ActiveProfiles("test") point the properties setup for tests (use : application-test.properties)
- Use MockMvc see Introducing Spring Test MVC HtmlUnit
So we have
@RunWith(SpringJUnit4ClassRunner.class
@SpringApplicationConfiguration(classes = Application.class)
@WebIntegrationTest({ "server.port=0", "management.port=0" })
@ActiveProfiles("test")
public class EnvControllerTest {
}
Then we declare our mock variable, wrap my web application context and a JPA repository :
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@Autowired
EnvRepository aRepository;
Then I can setup up my test with mock initialization and then repository setup
@Before
public void setup() throws Exception {
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
this.aRepository.deleteAll();
//init repositories...
}
At the end I could now use the mock calling URL, get response and verify it.
@Test
public void aNewTest() throws Exception {
ResultActions perform = mockMvc.perform(get("/restpath/1"));
MvcResult andReturn = perform.andReturn();
String res = andReturn.getResponse().getContentAsString();
}
Manage http error
A last small thing that test make thougt about... error processing managment.import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public class ErrorServerException extends RuntimeException {
private static final long serialVersionUID = -4464650477685224460L;
public ErrorServerException(String message) {
super("Server error : " + message + ".");
}
}
No comments:
Post a Comment