Skip to content
Snippets Groups Projects
Commit 2301edbf authored by Hallvard Trætteberg's avatar Hallvard Trætteberg
Browse files

Moved emf+osgi stuff to another OSGi workspace

parent 3dc4652d
No related branches found
No related tags found
No related merge requests found
Showing
with 302 additions and 16 deletions
......@@ -2,6 +2,8 @@
This OSGi project shows how an unmodular (monolithic, one-bundle) OSGi project is transformed into a modular, flexible one, in two steps. All three variants implements a simple web service for searching one or more dictionaries. Logically, all variants consist of a domain part, the dictionary- and search-related classes (among others, a **Dict** interface and its implementations) and the web service (a **Servlet**). Technically, the variants differ in how these parts are distributed among bundles and utilize the component mechanism.
In addition to the dict project, there is an (unrelated) example of how to use an EMF model developed using Eclipse PDE in an OSGi bundle (project) managed by Bnd(tools). The case is a REST API serving an EMF model instance, see [below](#emf-rest-in-osgi).
## Setup
The root project and folder was created using the BndTools' Bnd OSGi Workspace wizard, and each bundle with the Bnd OSGi Project wizard. Which bundle template to use depends on the specific bundle, there are api, component and servlet bundles in this project.
......
......@@ -58,18 +58,6 @@
pretty = true; \
local = ${build}/release
-plugin.EMF: aQute.bnd.repository.p2.provider.P2Repository; \
name = "EMF 2.19 Release"; \
url = "http://download.eclipse.org/modeling/emf/emf/builds/release/2.19"
-plugin.Acceleo: aQute.bnd.repository.p2.provider.P2Repository; \
name = "Acceleo Updates 3.7 Release"; \
url = "https://download.eclipse.org/acceleo/updates/releases/3.7"
-plugin.Ra: aQute.bnd.repository.p2.provider.P2Repository; \
name = "Local Ra repository"; \
url = "file:${build}/../../tdt4250.ra.repository"
-releaserepo: Release
-baselinerepo: Release
......
<?xml version='1.0' encoding='UTF-8'?>
<repository xmlns="http://www.osgi.org/xmlns/repository/v1.0.0" name="Local" increment="1568286905496"/>
<repository xmlns="http://www.osgi.org/xmlns/repository/v1.0.0" name="Local" increment="1569449476756"/>
cedf409ea38a6a13e0a64001bc4efe2bfbd9b1212750671d5aaaea52a658b65a
\ No newline at end of file
0f4ab43c8259f8770941c97370a69c94057545349c472b60455a3868043d7c19
\ No newline at end of file
<?xml version='1.0' encoding='UTF-8'?>
<repository xmlns="http://www.osgi.org/xmlns/repository/v1.0.0" name="Release" increment="1568286905501"/>
<repository xmlns="http://www.osgi.org/xmlns/repository/v1.0.0" name="Release" increment="1569449476759"/>
ea524b1f831740b9be82930dd5a0fdb50339e83f978e99477b66f7e840fa4fef
\ No newline at end of file
5268a56c364964c76e45f65d30b6e34866042e4542a5eae69fe71e863d1dd953
\ No newline at end of file
# Text files with LF eol
*.auth crlf=input
*.awk crlf=input
*.bnd crlf=input
*.bndrun crlf=input
*.c crlf=input ident
*.conf crlf=input
*.cpp crlf=input ident
*.css crlf=input
*.ddf crlf=input
*.ee crlf=input
*.gradle crlf=input
*.groovy crlf=input
*.h crlf=input ident
*.html crlf=input ident
*.java crlf=input ident
*.js crlf=input
*.lib crlf=input
*.md crlf=input
*.MF crlf=input
*.mf crlf=input
*.perm crlf=input
*.php crlf=input
*.pl crlf=input
*.pom crlf=input
*.prefs crlf=input
*.properties crlf=input
*.py crlf=input
*.schema crlf=input
*.SF crlf=input
*.sh crlf=input
*.tcl crlf=input
*.txt crlf=input
*.xml crlf=input
*.xsd crlf=input ident
*.xsl crlf=input
*.xslt crlf=input
*.yml crlf=input
.classpath crlf=input
.project crlf=input
gradlew crlf=input
packageinfo crlf=input
Makefile crlf=input
README crlf=input
LICENSE crlf=input
# No EOL translation
*.bat -crlf
# Binary. No EOL translation, no diff
*.ico binary
*.jpeg binary
*.jpg binary
*.png binary
*.crt binary
*.pdf binary
*.dll binary
*.jar binary
*.jnilib binary
*.so binary
*.zip binary
*.doc binary
*.ppt binary
*.xls binary
*.odg binary
*.odp binary
*.ods binary
*.odt binary
*.otg binary
*.otp binary
*.ots binary
*.ott binary
*.key binary
*.numbers binary
*.pages binary
.DS_Store
.gradle/
generated/
.metadata
File added
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
sudo: false
language: java
jdk:
- oraclejdk8
install: ./gradlew --version
script: ./gradlew --continue
# tdt4250.dict project
This OSGi project shows how an unmodular (monolithic, one-bundle) OSGi project is transformed into a modular, flexible one, in two steps. All three variants implements a simple web service for searching one or more dictionaries. Logically, all variants consist of a domain part, the dictionary- and search-related classes (among others, a **Dict** interface and its implementations) and the web service (a **Servlet**). Technically, the variants differ in how these parts are distributed among bundles and utilize the component mechanism.
In addition to the dict project, there is an (unrelated) example of how to use an EMF model developed using Eclipse PDE in an OSGi bundle (project) managed by Bnd(tools). The case is a REST API serving an EMF model instance, see [below](#emf-rest-in-osgi).
## Setup
The root project and folder was created using the BndTools' Bnd OSGi Workspace wizard, and each bundle with the Bnd OSGi Project wizard. Which bundle template to use depends on the specific bundle, there are api, component and servlet bundles in this project.
To make your own OSGi project with a similar structure, it's best to start with a fresh Eclipse workspace, create a Bnd OSGi Workspace there and the bundles one by one, making sure to "guess" the right template to use. To be able to glance at this example while working on your own, open the example workspace in a *different* Eclipse installation, since it's difficult to open the same Eclipse one different workspaces simultaneously.
To run the project, you should open the launch.bndrun file in the servlet bundle, make sure it resolves and use **Run OSGi**. You can try various commands in the gogo shell, e.g. **felix:lb** to see which bundles are in which states or **scr:list** to se the active components, and do a dictionary lookup using **http://localhost:8080/dict?q=master** in a browser.
## Variant 1
The first variant consists of the [tdt4250.dict1.servlet](tdt4250.dict1.servlet/README.md) bundle, which was created using the Servlet Component template. It contains both the logic for dictionary search and the **Servlet**, i.e. it is unmodular. It's also inflexible, since the set of dictionaries is hard-coded into the **Servlet** implementation class.
### Packages
- **tdt4250.dict1.core**: The core interfaces and classes that will be used by dictionary users and implementations. There's a **Dict** interface, a **DictSearch** class managing search within a set of **Dict**s and a **DictSearchResult** class for the search result.
- **tdt4250.dict1.no**: An implementation of the **Dict** interface that loads a Norwegian dictionary from a file, with supporting classes.
- **tdt4250.dict1.servlet**: The **Servlet** component (i.e. implementation annotated with **@Component**) implementing a web service for searching a set of dictionaries (currently just the Norwegian one).
## Variant 2
The second variant consists of the [tdt4250.dict2.core](tdt4250.dict2.core/README.md) and [tdt4250.dict2.servlet](tdt4250.dict2.servlet/README.md) bundles. It's somewhat modular, since it's split into at least two bundles. It's also inflexiblie, since the set of dictionaries is still hard-coded into the Servlet implementation class.
### Bundles and packages
* **tdt4250.dict2.core**
* **tdt4250.dict2.core**: Same core interfaces and classes of variant 1.
* **tdt4250.dict2.no**: Same **Dict** implementation and supporting classes as in variant 1.
* **tdt4250.dict2.servlet**
* **tdt4250.dict2.servlet**: The same **Servlet** component with hard-coded set of dictionaries (currently just the Norwegian one).
## Variant 3
The third variant consists of the [tdt4250.dict3.api](tdt4250.dict3.api/README.md), [tdt4250.dict3.util](tdt4250.dict3.util/README.md), [tdt4250.dict3.no](tdt4250.dict3.no/README.md), [tdt4250.dict3.servlet](tdt4250.dict3.servlet/README.md) (and [tdt4250.dict3.rest](tdt4250.dict3.rest/README.md) and [tdt4250.dict3.gogo](tdt4250.dict3.gogo/README.md) bundles. It's modular, being split into bundles with minimal dependencies, and flexible, since new bundles can contribute additional dictionaries as components.
### Bundles and packages
* **tdt4250.dict3.api**
* **tdt4250.dict3.api**: Same core interfaces and classes of variant 2.
* **tdt4250.dict3.util**:
* **tdt4250.dict3.util**:
* **tdt4250.dict3.util.internal**:
* **tdt4250.dict3.no**: Same **Dict** implementation as in variant 2.
* **tdt4250.dict3.no**: Same **Dict** implementation and supporting classes as in variant 1.
* **tdt4250.dict3.servlet**
* **tdt4250.dict3.servlet**: The same **Servlet** implementation, but now depending on (injected) **Dict** services to make it more flexible.
* **tdt4250.dict3.gogo**
* **tdt4250.dict3.gogo**: Gogo shell commands for managing **Dict** service components.
## EMF REST in OSGi
This (unrelated) part of this example shows how to serve an EMF instance in a REST API. There's two neat things with this example:
* the REST API servlet is generic, so it can serve any EMF model instance, optionally guided by model annotations
* the EMF project bundles are built by Eclipse PDE (outside this OSGi project), and used here
### Generic EMF REST servlet
You can think of a REST API as a way of navigating from a set of root objects to some objects of interest and either reading or operating on them. Navigation is done along associations (references in Ecore terminologi) and you can typically filter and select while navigating. The result is typically serialized back as Json.
If you're doing this in pure Java, you can use a combination of reflection and annotations to do this generically. The **tdt4250.emf.*** bundles provide the same for EMF: generic REST API access to any EMF model instance driven by the model:
* **tdt4250.emf.servletsupport**: Service interfaces for various aspects of the the REST API, like navigating along associations, applying a final operation and serializing the result.
* **tdt4250.emf.servletsupport.impl**: Generic implementation of the service interfaces
* **tdt4250.emf.servlet.**: The end-point that decodes a request and uses the services. It supports any set of named resources, so the first path segment is the resources to access, and the rest is the REST path and optional query/operation.
### Making EMF model bundles available for OSGi
To test the generic REST support, a resource allocation model (for university staff and courses) is used. This corresponding EMF model project (in general PDE bundle/plugin projects) is outside and in the same folder as the OSGi workspace. The layout is as follows
* **examples** - the git repo folder
* **dict-ws** - the OSGi workspace
* **cnf** - OSGi workspace configuration project
* **tdt4250.emf.*** - bundle project providing REST servlet
* **tdt4250.ra.resource - bundle providing a sample EMF resource (instance of ra model) to serve
* tdt4250.ra - EMF resource allocation model project
* tdt4250.ra.feature - features to publish in p2 repository
* tdt4250.ra.repository - p2 repository project
// Available to customize the build
wrapper {
jarFile = rootProject.file('.gradle-wrapper/gradle-wrapper.jar')
}
/cache/
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>cnf</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>
# Configure Repositories
-plugin.1.R7.API: \
aQute.bnd.repository.maven.pom.provider.BndPomRepository; \
snapshotUrls=https://oss.sonatype.org/content/repositories/osgi/; \
releaseUrls=https://repo.maven.apache.org/maven2/; \
revision=org.osgi.enroute:osgi-api:7.0.0; \
readOnly=true; \
name="OSGi R7 API"
-plugin.2.Enterprise.API: \
aQute.bnd.repository.maven.pom.provider.BndPomRepository; \
snapshotUrls=https://oss.sonatype.org/content/repositories/osgi/; \
releaseUrls=https://repo.maven.apache.org/maven2/; \
revision=org.osgi.enroute:enterprise-api:7.0.0; \
readOnly=true; \
name="Enterprise Java APIs"
-plugin.3.R7.Impl: \
aQute.bnd.repository.maven.pom.provider.BndPomRepository; \
snapshotUrls=https://oss.sonatype.org/content/repositories/osgi/; \
releaseUrls=https://repo.maven.apache.org/maven2/; \
revision=org.osgi.enroute:impl-index:7.0.0; \
readOnly=true; \
name="OSGi R7 Reference Implementations"
-plugin.4.Test: \
aQute.bnd.repository.maven.pom.provider.BndPomRepository; \
snapshotUrls=https://oss.sonatype.org/content/repositories/osgi/; \
releaseUrls=https://repo.maven.apache.org/maven2/; \
revision=org.osgi.enroute:test-bundles:7.0.0; \
readOnly=true; \
name="Testing Bundles"
-plugin.5.Debug: \
aQute.bnd.repository.maven.pom.provider.BndPomRepository; \
snapshotUrls=https://oss.sonatype.org/content/repositories/osgi/; \
releaseUrls=https://repo.maven.apache.org/maven2/; \
revision=org.osgi.enroute:debug-bundles:7.0.0; \
readOnly=true; \
name="Debug Bundles"
-plugin.6.Central: \
aQute.bnd.repository.maven.provider.MavenBndRepository; \
releaseUrl=https://repo.maven.apache.org/maven2/; \
index=${.}/central.maven; \
readOnly=true; \
name="Maven Central"
-plugin.7.Local: \
aQute.bnd.deployer.repository.LocalIndexedRepo; \
name = Local; \
pretty = true; \
local = ${build}/local
-plugin.8.Templates: \
aQute.bnd.deployer.repository.LocalIndexedRepo; \
name = Templates; \
pretty = true; \
local = ${build}/templates
-plugin.9.Release: \
aQute.bnd.deployer.repository.LocalIndexedRepo; \
name = Release; \
pretty = true; \
local = ${build}/release
-plugin.EMF: aQute.bnd.repository.p2.provider.P2Repository; \
name = "EMF 2.19 Release"; \
url = "http://download.eclipse.org/modeling/emf/emf/builds/release/2.19"
-plugin.Acceleo: aQute.bnd.repository.p2.provider.P2Repository; \
name = "Acceleo Updates 3.7 Release"; \
url = "https://download.eclipse.org/acceleo/updates/releases/3.7"
-plugin.Ra: aQute.bnd.repository.p2.provider.P2Repository; \
name = "Local Ra repository"; \
url = "file:${build}/../../tdt4250.ra.repository"
-releaserepo: Release
-baselinerepo: Release
# Always use contracts
-contract: *
# Set Git revision information in the manifests of built bundles
Git-Descriptor: ${system-allow-fail;git describe --dirty --always}
Git-SHA: ${system-allow-fail;git rev-list -1 HEAD}
# JUnit
junit: org.apache.servicemix.bundles.junit; version=4.12
mockito: org.mockito.mockito-core; version=2.13.0
mockito-deps: org.objenesis; version=2.6.0,\
net.bytebuddy.byte-buddy; version=1.7.9,\
net.bytebuddy.byte-buddy-agent; version=1.7.9
# List repository contents using GAV coordinates
com.fasterxml.jackson.core:jackson-core:2.9.8
com.fasterxml.jackson.core:jackson-annotations:2.9.8
com.fasterxml.jackson.core:jackson-databind:2.9.8
#com.fasterxml.jackson.jaxrs:jackson-jaxrs-base:2.9.8
#com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.9.8
#com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.9.8
#org.apache.aries.jax.rs:org.apache.aries.jax.rs.jackson:1.0.2
<?xml version='1.0' encoding='UTF-8'?>
<repository xmlns="http://www.osgi.org/xmlns/repository/v1.0.0" name="Local" increment="1569449476756"/>
0f4ab43c8259f8770941c97370a69c94057545349c472b60455a3868043d7c19
\ No newline at end of file
<?xml version='1.0' encoding='UTF-8'?>
<repository xmlns="http://www.osgi.org/xmlns/repository/v1.0.0" name="Release" increment="1569449476759"/>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment