Ch. 7 Maintaining a Project
At this point, we have used Jellyfish to generate four services and one system. In this chapter, we’ll learn how to make model changes and incorporate them into services and systems that have already been generated.
Once we have initially generated projects with Jellyfish, we typically no longer need to run Jellyfish directly. Instead, we use Gradle to build and maintain our generated projects.
Gradle and Jellyfish
Gradle actually uses Jellyfish internally when a service project is being built. So even though Jellyfish isn't being
used directly, it's still being used indirectly by Gradle during a build.
Updating the Model
Assume that it is necessary to make a change to the SoftwareRequestService
. The service is being updated so that
requests can be emailed as attachments directly to the system. We’ll update model to include an additional input
and a new scenario:
SoftwareRequestService.sd
model SoftwareRequestService {
metadata {
"stereotypes" : ["service"],
"codegen": {
"alias": "srs"
}
}
input {
InstallationRequest installationRequest
EmailMessage emailedInstallationRequest
}
output {
UnapprovedRequest unapprovedRequest
}
scenario processRequest {
when receiving installationRequest
then willPublish unapprovedRequest
}
scenario processEmailedRequest {
when receiving emailedInstallationRequest
then willPublish unapprovedRequest
}
}
We now need to update the inputs and links in the top level SoftwareStore
system:
SoftwareStore.sd
model SoftwareStore {
input {
InstallationRequest installationRequest
EmailMessage emailedInstallationRequest // This input is new
}
// ... (omitted)
links {
link emailedInstallationRequest -> softwareRequestService.emailedInstallationRequest // this link is new
link installationRequest -> softwareRequestService.installationRequest
// ... (omitted)
}
}
Finally, we can also include a new top-level scenario:
SoftwareStore.sd
scenario handleEmailedInstallationRequest {
when receiving emailedInstallationRequest
then willPublish emailMessage
}
Our modeling changes are complete. We now need to publish this new version of the model. Before doing this, we need to
update the version of the model project itself. We can do this by editing the value of the version
property in the SD
project’s build.gradle
file:
Setting the version in build.gradle
version = '1.1.0-SNAPSHOT'
Note the previous version was 1.0.0-SNAPSHOT
. In keeping with the principles of
Semantic Versioning, we’ve updated the version to 1.1.0-SNAPSHOT
. We can now build and upload
the project to a remote repository with ./gradlew clean build publish
.
Update the Service and System
Now that a new version of the model has been published, we can update our existing services and system. We do not need
to re-run Jellyfish. Instead, we can just edit the build.gradle
file of the service project
com.helpco.helpdesk.softwarerequestservice
. This is the build file for the root project. The file contains the
following section:
build.gradle
systemDescriptor {
project = 'com.ngc.seaside:helpdesk.descriptor:1.0.0-SNAPSHOT'
model = 'com.helpco.helpdesk.SoftwareRequestService'
deploymentModel = 'com.helpco.helpdesk.LocalSoftwareStore'
}
Note the line project = 'com.ngc.seaside:helpdesk.descriptor:1.0.0-SNAPSHOT'
. This configures which version of the
SD project should be referenced. Replace 1.0.0-SNAPSHOT
with 1.1.0-SNAPSHOT
:
build.gradle
systemDescriptor {
project = 'com.ngc.seaside:helpdesk.descriptor:1.1.0-SNAPSHOT'
model = 'com.helpco.helpdesk.SoftwareRequestService'
deploymentModel = 'com.helpco.helpdesk.LocalSoftwareStore'
}
Now perform a new build with the command ./gradlew clean build
. The project will not compile due to errors in
the sub-project com.helpco.helpdesk.softwarerequestservice.impl
. This is due to a missing method that is not
implemented. This error is the result of adding a new scenario to SoftwareRequestService
model. An IDE can
automatically generate this method, or we can manually create it in the SoftwareRequestService
class:
SoftwareRequestService.java
@Override
public UnapprovedRequest doProcessEmailedRequest(EmailMessage emailedInstalledRequest) throws ServiceFaultException {
// TODO: implement this
throw new UnsupportedOperationException("not implemented");
}
The project should now correctly build.
Updating the remaining services and system is similar. Simply update the build.gradle
file of each root project.
Conclusion
When making model changes, always release a new version of the model. Then update the build.gradle
file of each
dependent service to reference the new version of the model. Simply running ./gradlew clean build
will update the
generated projects. It is not necessary to run Jellyfish directly again.