|
|
|
# This is a preliminary tutorial set up a Connected Service to the Sharing Platform
|
|
|
|
|
|
|
|
(Based on Connector-Interface v0.1.2)
|
|
|
|
|
|
|
|
You can download a simple sample implementation of a connected service at https://sharing-codeability.uibk.ac.at/development/sharing/sharing-plugin-demo.
|
|
|
|
|
|
|
|
Disclaimer: This is not yet a fully blown tutorial. It only shows the major steps. Details can be found in the sample implementation.
|
|
|
|
|
|
|
|
## 0. SetUp Test Environment
|
|
|
|
|
|
|
|
To make your connected service testable, you should ask for an integration in the test sharing plattform at https://dev-exchange.codeability-austria.uibk.ac.at/.
|
|
|
|
To configure your tests, you must make your configuration Rest service publicly available under an URL that is reachable from the sharing plattform. The ```actionTransferURL``` can be an internal URL valid in your local browser.
|
|
|
|
|
|
|
|
Alternatively, you can install a local version of the sharing plattform. The developer team can provide you with further information how to share the access to the test infrastructure of the gitlab and elasticsearch index via ssh tunnels.
|
|
|
|
|
|
|
|
## 1. Dependency
|
|
|
|
|
|
|
|
For maven include
|
|
|
|
```xml
|
|
|
|
<dependency>
|
|
|
|
<groupId>org.codeability.sharing</groupId>
|
|
|
|
<artifactId>SharingPluginPlatformAPI</artifactId>
|
|
|
|
<version>0.1.2</version>
|
|
|
|
</dependency>
|
|
|
|
```
|
|
|
|
from repository
|
|
|
|
```xml
|
|
|
|
<repository>
|
|
|
|
<id>codabilitySharingAPIRepository</id>
|
|
|
|
<name>codability Sharing API Repository via git</name>
|
|
|
|
<url>https://sharing-codeability.uibk.ac.at/development/sharing/codeabilitysharingpluginapi/-/raw/master/target/</url>
|
|
|
|
</repository>
|
|
|
|
```
|
|
|
|
## 2. Provide public Config Service
|
|
|
|
See classes SharingSupportResource and SharingSupportResource
|
|
|
|
|
|
|
|
This provides a config Rest service at
|
|
|
|
http://localhost:8080/api/sharingPluginConfig
|
|
|
|
|
|
|
|
In the Demo-Example we define a rest service
|
|
|
|
```java
|
|
|
|
@GetMapping("/sharingPluginConfig")
|
|
|
|
public ResponseEntity<SharingPluginConfig> getConfig(@RequestHeader("Authorization") String bearer,
|
|
|
|
@RequestParam String apiBaseUrl, @RequestParam String installationName) {
|
|
|
|
```
|
|
|
|
|
|
|
|
This service takes two request parameters `apiBaseUrl` and `installationName`. Additional it takes as further parameter the `Authorization`-header. The header value typically has the form `Bearer <<access key>>, and must be checked accordingly.
|
|
|
|
|
|
|
|
Ensure that this service is accessible from everywhere (or at least from the sharing platform).
|
|
|
|
For our spring boot aplication, we have to exempt this service from spring security by
|
|
|
|
```java
|
|
|
|
web.ignoring()
|
|
|
|
...
|
|
|
|
.antMatchers("/api/sharingPluginConfig")
|
|
|
|
```
|
|
|
|
|
|
|
|
The returned configuration is something like
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"version" : "0.1",
|
|
|
|
"pluginName" : "Demo Sharing Plugin Connector",
|
|
|
|
"actions" : [ {
|
|
|
|
"actionId" : "DemoAction1",
|
|
|
|
"actionTransferURL" : "/sharingPluginLandingPage",
|
|
|
|
"actionName" : "Transfer Collection to Demo Plugin",
|
|
|
|
"filterELExpression" : "metadata.type.externalName=='collections'"
|
|
|
|
}, {
|
|
|
|
"actionId" : "DemoAction2",
|
|
|
|
"actionTransferURL" : "/sharingPluginLandingPage",
|
|
|
|
"actionName" : "Transfer Programming Exercise to Demo Plugin",
|
|
|
|
"filterELExpression" : "metadata.type.externalName=='programming exercise'"
|
|
|
|
} ]
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
The demo plugin provides two actions
|
|
|
|
- one action for collections
|
|
|
|
- another action for programming exercises
|
|
|
|
|
|
|
|
Together with the request for the connector configuration the sharing platform also transfers two parameters for further info:
|
|
|
|
- apiBaseUrl: the base url for the call backs to the sharing plattform (e.g. ´https://sharing.codeability-austria.uibk.ac.at/api´)
|
|
|
|
- installationName: an informative name for the current installation (e.g. `sharing plattform (prod)`
|
|
|
|
|
|
|
|
Also it optionaly transfers in the Authentication header a bearer token to identify itself as a valid sharing platform.
|
|
|
|
|
|
|
|
## 3. Implement a Landing Page for each action
|
|
|
|
|
|
|
|
The Landing Page is invoked as e.g. http://localhost:8080/sharingPluginLandingPage/67b1f6b5-610d-4e65-a161-ab24f478ad01?returnURL=https:%2F%2Fdev-exchange.codeability-austria.uibk.ac.at&apiBaseURL=https:%2F%2Fdev-exchange.codeability-austria.uibk.ac.at%2Fapi%2FpluginIF%2Fv0.1
|
|
|
|
|
|
|
|
Implement a landing page, that can analyze the URL and extract the relevant Parameters for the basket token (e.g. 67b1f6b5-610d-4e65-a161-ab24f478ad01) and the url parameters apiBaseURL and returnURL respectively.
|
|
|
|
|
|
|
|
An implementation example based on Angluar can be found in the plugin demo in [app-routing.module.ts](https://sharing-codeability.uibk.ac.at/development/sharing/sharing-plugin-demo/-/blob/master/src/main/webapp/app/app-routing.module.ts)
|
|
|
|
```typescript
|
|
|
|
// ===== Sharing Import/Export =====
|
|
|
|
{
|
|
|
|
path: 'sharingPluginLandingPage/:basketToken',
|
|
|
|
loadChildren: () => import('./sharing/sharing.module' ).then((m) => m.SharingModule),
|
|
|
|
},
|
|
|
|
|
|
|
|
```
|
|
|
|
and [sharing.component.ts](https://sharing-codeability.uibk.ac.at/development/sharing/sharing-plugin-demo/-/blob/master/src/main/webapp/app/sharing/sharing.component.ts)
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
constructor(
|
|
|
|
private route: ActivatedRoute,
|
|
|
|
public sharingInfo: SharingInfo,
|
|
|
|
private sharingDemoService: SharingDemoService,
|
|
|
|
|
|
|
|
) {
|
|
|
|
this.route.params.subscribe((params) => {
|
|
|
|
sharingInfo.basketToken = params['basketToken'];
|
|
|
|
});
|
|
|
|
this.route.queryParams.subscribe((qparam) => {
|
|
|
|
sharingInfo.returnURL = qparam['returnURL'];
|
|
|
|
sharingInfo.apiBaseURL = qparam['apiBaseURL'];
|
|
|
|
this.loadShoppingBasket();
|
|
|
|
});
|
|
|
|
this.shoppingBasket = {} as ShoppingBasket;
|
|
|
|
this.readme = new Array(10) ;
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
## 4. Implement the connected service's functionality
|
|
|
|
|
|
|
|
On the backend implement a Rest Client that can retrieve the relevant basket infos from the Sharing Platform.
|
|
|
|
|
|
|
|
In the frontend implement the relevant service calls to the backend (see e.g. [sharing-demo.service.ts](https://sharing-codeability.uibk.ac.at/development/sharing/sharing-plugin-demo/-/blob/master/src/main/webapp/app/sharing/service/sharing-demo.service.ts)).
|
|
|
|
|
|
|
|
See as example [SharingDemoService.java](https://sharing-codeability.uibk.ac.at/development/sharing/sharing-plugin-demo/-/blob/master/src/main/java/org/codeability/sharing/demo/service/SharingDemoService.java):
|
|
|
|
|
|
|
|
``` java
|
|
|
|
public Optional<ShoppingBasket> getBasketInfo(SharingInfoDTO sharingInfo) {
|
|
|
|
ClientConfig restClientConfig = new ClientConfig();
|
|
|
|
restClientConfig.register(ShoppingBasket.class);
|
|
|
|
Client client = ClientBuilder.newClient(restClientConfig);
|
|
|
|
|
|
|
|
WebTarget target = client.target(sharingInfo.getApiBaseURL()+"/basket/"+sharingInfo.getBasketToken());
|
|
|
|
|
|
|
|
// TODO make error proof
|
|
|
|
ShoppingBasket shoppingBasket = target.
|
|
|
|
request().
|
|
|
|
accept(MediaType.APPLICATION_JSON).
|
|
|
|
get(ShoppingBasket.class);
|
|
|
|
return Optional.of(shoppingBasket);
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Based on this service you can now implement your own functionality.
|
|
|
|
|
|
|
|
## 5. Use the search functionality
|
|
|
|
|
|
|
|
You can also invoke the search functionality of the sharing plattform.
|
|
|
|
Find an example implementation in the demo, and further info in the [documentation](technical/Connector-Interface) |