From 13d801e75a77e0269e840e0ac74fda8418480d68 Mon Sep 17 00:00:00 2001 From: Aaron Coburn Date: Mon, 27 Feb 2023 17:50:17 -0500 Subject: [PATCH 1/4] JCL-73: Reorganize, rework high-level documentation --- README.md | 4 +- src/site/apt/data-modeling.apt.vm | 147 +++++++++++++++++++ src/site/apt/getting-started.apt.vm | 41 ++++++ src/site/apt/gettingStarted.apt.vm | 122 ---------------- src/site/apt/index.apt.vm | 135 +---------------- src/site/apt/session-management.apt.vm | 195 +++++++++++++++++++++++++ src/site/apt/setUp.apt.vm | 89 ----------- src/site/apt/usage-examples.apt.vm | 138 +++++++++++++++++ src/site/site.xml | 6 +- 9 files changed, 531 insertions(+), 346 deletions(-) create mode 100644 src/site/apt/data-modeling.apt.vm create mode 100644 src/site/apt/getting-started.apt.vm delete mode 100644 src/site/apt/gettingStarted.apt.vm create mode 100644 src/site/apt/session-management.apt.vm delete mode 100644 src/site/apt/setUp.apt.vm create mode 100644 src/site/apt/usage-examples.apt.vm diff --git a/README.md b/README.md index 78a6580dc1a..61abb9792d5 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ The Inrupt Java Client Libraries provide highly flexible, simple components that ## Using the libraries as a dependency in your own projects -To use the Inrupt Java Client Libraries in your projects make sure to visit the [Set Up page](https://inrupt.github.io/solid-client-java/setUp.html) of the documentation. +To use the Inrupt Java Client Libraries in your projects make sure to visit the [Getting Started page](https://inrupt.github.io/solid-client-java/getting-started.html) of the documentation. Next we will document how to use this repository locally. @@ -70,4 +70,4 @@ forum is a good place to meet the rest of the community. ## License -MIT © [Inrupt](https://inrupt.com) \ No newline at end of file +MIT © [Inrupt](https://inrupt.com) diff --git a/src/site/apt/data-modeling.apt.vm b/src/site/apt/data-modeling.apt.vm new file mode 100644 index 00000000000..e2f92ded0fa --- /dev/null +++ b/src/site/apt/data-modeling.apt.vm @@ -0,0 +1,147 @@ +Data Modeling + + The high-level <<>> and <<>> make it easy to bind your Java objects to RDF-based Solid resources. This guide will help you structure your class definitions to make this possible. + +* What you will need + + * About 15 minutes + + * Your favorite text editor or IDE + + * Java 11 or later + + * Maven 3.5 or later + +* Solution + + The solution involves creating a wrapper class so that your class can act not only as an RDF Graph + but also as a domain-specific type. + +* 1. Subclass the Resource type + + The first step involves ensuring that your class extends the <<>> class + and consider the methods you expect in your class. + ++--- +public class Playlist extends Resource { + + public Playlist(URI identifier, Dataset dataset) { + super(identifier, dataset); + } + + public String getTitle() { + ... + } + + public void setTitle(String title) { + ... + } + + public Set getSongs() { + ... + } + + public void addSong(URI song) { + ... + } +} ++--- + + +* 2. Create the wrapper node + + Next, you will create an inner class that binds the data between RDF and your class. + ++--- +public class Playlist extends Resource { + + ... + + static IRI DC_TITLE = rdf.createIRI("http://purl.org/dc/terms/title"); + static IRI EX_SONG = rdf.createIRI("http://music.example/song"); + + static class Node extends WrapperIRI { + Node(RDFTerm original, Graph graph) { + super(original, graph); + } + + String getTitle() { + return anyOrNull(DC_TITLE, ValueMappings::literalAsString); + } + + void setTitle(String value) { + overwriteNullable(DC_TITLE, value, TermMappings::asStringLiteral); + } + + Set getSongs() { + return objects(EX_SONG, TermMappings::asIri, ValueMappings::iriAsUri); + } + + void addSong(URI song) { + add(EX_SONG, song, TermMappings::asIri); + } + } +} ++--- + +* 3. Connect your public methods to the wrapper node + + Now you are ready to link your public methods to the methods from your inner class. + ++--- +public class Playlist extends Resource { + + private Node subject; + + public Playlist(URI identifier, Dataset dataset) { + super(identifier, dataset); + + subject = new Node(rdf.createIRI(identifier.toString()), dataset.getGraph()); + } + + public String getTitle() { + return subject.getTitle(); + } + + public void setTitle(String title) { + subject.setTitle(title); + } + + public Set getSongs() { + return subject.getSongs(); + } + + public void addSong(URI song) { + subject.addSong(song); + } + + ... +} ++--- + +* 4. Use your class in the high-level client + + Now, you can use your class with the high-level Solid client, mapping data seamlessly between your + Java application and an RDF resource. + ++--- +public class MyApplication { + + public void run() { + Session session = OpenIdConnect.ofClientCredentials(issuer, clientId, clientSecret, "client_secret_basic"); + SolidSyncClient client = SolidSyncClient.getClient().session(session); + + URI uri = URI.create("https://storage.example/playlists/910b509c-1ca5-4d6a-a093-377e8e1b390e"); + try (Playlist playlist = client.read(uri, Playlist.class)) { + System.out.println(playlist.getTitle()); + + // Add a new song to the playlist + playlist.addSong(song); + + // Update the playlist in your storage + client.update(playlist); + } + } +} ++--- + diff --git a/src/site/apt/getting-started.apt.vm b/src/site/apt/getting-started.apt.vm new file mode 100644 index 00000000000..591c4d84d9b --- /dev/null +++ b/src/site/apt/getting-started.apt.vm @@ -0,0 +1,41 @@ +Getting Started With Inrupt's Java Client Libraries + + This guide will help you set up Java project using Maven. This project will contain all the necessary components to begin building a Solid application in Java. + +* What you will need + + * About 15 minutes + + * Your favorite text editor or IDE + + * Java 11 or later + + * Maven 3.5 or later + +* How to complete + + First, issue the following command: + +----------------- +$ mvn archetype:generate \ + -DarchetypeGroupId=com.inrupt \ + -DarchetypeArtifactId=inrupt-client-archetype-java +----------------- + + You will be prompted for a <<>> value (e.g. <<>>) and an <<>> value (e.g. <<>>). + + Next, you will be able to find your new project in your current working directory. + + To build this new project, issue the following commands: + +----------------- +$ cd sample-project +$ mvn install +----------------- + +* Next steps + + Your project will be configured to use a recommended collection of dependencies and provides a simple starting point for + building a Solid Application. + + Next, you will need to consider whether to use a synchronous or asynchronous client for your application, as described in the {{{./usage-examples.html}usage examples}}. diff --git a/src/site/apt/gettingStarted.apt.vm b/src/site/apt/gettingStarted.apt.vm deleted file mode 100644 index d6649009399..00000000000 --- a/src/site/apt/gettingStarted.apt.vm +++ /dev/null @@ -1,122 +0,0 @@ -Getting Started - - An app developer will first need to consider how a user creates an authenticated session. Depending on the application framework in use, there may already be - a valid OpenID Id Token. Alternatively, a developer may possess a set of client credentials. Both approaches are described below. In both cases, a client object - will be needed: - ----------------------- -var CLIENT = SolidSyncClient.getClient(); ----------------------- - -* Using an existing ID Token - - All interactions with Solid resources happen in the context of a <<>>. If an existing Id Token is available, the <<>> can use that value. In this - case, it will be the responsibility of the application framework to refresh the Id Token upon expiration. - ----------------------- -var session = OpenIdSession.ofIdToken(idToken); -var client = CLIENT.session(session); ----------------------- - -* Using OAuth2 Client Credentials - - Using <<>>, an app developer can create a session that automatically refreshes upon token expiration. - ----------------------- -var session = OpenIdSession.ofClientCredentials(issuer, clientId, clientSecret, authMethod); -var client = CLIENT.session(session); ----------------------- - - With this <<>> object, one can perform normal CRUD operations on Solid resources. - Please note that, with <<>>, all operations are synchronous. For asynchronous operations, use <<>>. - ----------------------- -try (var playlist = client.read(uri, Playlist.class)) { - displayTitle(playlist.getTitle()); - displaySongs(playlist.getSongs()); -} ----------------------- - - One may also create new resources. - ----------------------- -var playlist = new Playlist(uri); -playlist.setTitle("Jazz Collection"); -playlist.addSong(song1); -playlist.addSong(song2); - -client.create(playlist); ------------------------ - - Or update existing resources. - ------------------------ -try (var playlist = client.read(uri, Playlist.class)) { - - playlist.setTitle("Bossa Nova"); - playlist.removeSong(song1); - playlist.addSong(song3); - - client.update(playlist); -} ------------------------ - - Or delete resources. - ------------------------ -client.delete(uri); ------------------------ - - One can use the provided Solid classes to list resources across a user's storage locations. - ------------------------ -session.getPrincipal().ifPresent(webid -> { - LOGGER.info("WebID: {}", webid); - try (final var profile = client.read(webid, WebIdProfile.class)) { - profile.getStorage().stream().findFirst().ifPresent(storage -> { - try (final var container = client.read(storage, SolidContainer.class); - final var stream = container.getContainedResources()) { - stream.filter(r -> filterResource(r, cmd)).forEach(r -> { - LOGGER.info("Resource: {}, {}", r.getIdentifier(), - principalType(r.getMetadata().getType())); - }); - } - }); - } -}); ------------------------ - -* Example applications - -** A sample Web Application - - The {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/examples/webapp/package-summary.html}web app example}} is a Quarkus application implementing a similar pattern to look up a user's WebID profile and then display the contents of a user's storage. - - To set up the example application the following configuration values need to be added for this to work properly: - ---------------------- -quarkus.oidc.auth-server-url= -quarkus.oidc.client-id= ---------------------- - - Remark: <<>> is a {{{https://solidproject.org/TR/oidc#clientids-document}Client ID Document}}. - - The above configuration values are typically added to a <<<./config/application.properties>>> file in the directory where the application is run. - - To build the application, use this command: - ---------------------- -$ ./mvnw package ---------------------- - - To run the application, use this command: - ---------------------- -$ java -jar examples/webapp/target/quarkus-app/quarkus-run.jar ---------------------- - - The application will be available at <<>>. - -** A sample CLI Application - - The {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/examples/webapp/package-summary.html}cli app example}} is a CLI utility application interacting with a Solid Storage. It is making use of OAuth2 Client Credentials to access the Pod Storage. diff --git a/src/site/apt/index.apt.vm b/src/site/apt/index.apt.vm index a644eaf5b7c..a1b8b913dbe 100644 --- a/src/site/apt/index.apt.vm +++ b/src/site/apt/index.apt.vm @@ -1,137 +1,10 @@ Inrupt's Java Client Libraries - {{{https://inrupt.com}Inrupt}} provides the following Java client libraries to help developers create {{{https://solidproject.org}Solid}} applications. These libraries provide highly flexible, simple components that can be used in any Java application for {{{https://solidproject.org/TR/protocol}Solid}}. The libraries are composed of different modules that follow a layered architectural approach. + {{{https://inrupt.com}Inrupt}} provides the following Java client libraries to help developers create {{{https://solidproject.org}Solid}} applications. These libraries provide highly flexible, simple components that can be used in any Java application for {{{https://solidproject.org/TR/protocol}Solid}}. -*-------*-----------------*--------*--------------* -|| Layer || Module function || Module || Description | -*-------*-----------------*--------*--------------* -|| Interface Layer | Central abstractions | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/package-summary.html}api}} | A layer that defines all the central abstractions used by the Java Client Libraries. | -*-------*-----------------*--------*--------------* -| | Central abstractions | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/auth/package-summary.html}auth}} | Authentication related abstractions used by the Java Client Libraries. | -*-------*-----------------*--------*--------------* -| | Central abstractions | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/spi/package-summary.html}spi}} | Service interfaces used by the Java Client Libraries. | -*-------*-----------------*--------*--------------* -| | Central abstractions | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/util/package-summary.html}util}} | Utility classes for the Java Client Libraries. | -*-------*-----------------*--------*--------------* -|| Core Modules Layer | HTTP interaction | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/httpclient/package-summary.html}httpclient}} | Http client based on the java.net implementation. | -*-------*-----------------*--------*--------------* -| | HTTP interaction | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/okhttp/package-summary.html}okhttp}} | Http client based on the OK HTTP implementation. | -*-------*-----------------*--------*--------------* -| | JSON processing | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/jackson/package-summary.html}jackson}} | JSON processing based on jackson. | -*-------*-----------------*--------*--------------* -| | JSON processing | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/jsonb/package-summary.html}jsonb}} | JSON processing that uses the JSON-B library. | -*-------*-----------------*--------*--------------* -| | RDF processing | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/jena/package-summary.html}jena}} | RDF processing based on the Jena implementation. | -*-------*-----------------*--------*--------------* -| | RDF processing | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/rdf4j/package-summary.html}rdf4j}} | RDF processing based on the RDF4J implementation. | -*-------*-----------------*--------*--------------* -| | Authentication & authorization | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/openid/package-summary.html}openid}} | Authentication logic based on OpenID & OAuth specification. | -*-------*-----------------*--------*--------------* -| | Authentication & authorization | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/uma/package-summary.html}uma}} | Authorization logic based on UMA specification. | -*-------*-----------------*--------*--------------* -|| Domain-Specific Modules Layer | Implementations of API interfaces | {{{corehttps://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/core/package-summary.html}core}} | Provides default implementations for different services. | -*-------*-----------------*--------*--------------* -| | Solid related data models | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/solid/package-summary.html}solid}} | Solid resource & container handlers. | -*-------*-----------------*--------*--------------* -| | WebID Profile data model | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/webid/package-summary.html}webid}} | Solid WebID handler. | -*-------*-----------------*--------*--------------* -|| Utility Modules | RDF Vocabulary terms | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/vocabulary/package-summary.html}vocabulary}} | Provides convenience objects for Solid-related identifiers. | -*-------*-----------------*--------*--------------* -| | Test utilities | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/test/package-summary.html}test}} | Common tests shared across library modules. | -*-------*-----------------*--------*--------------* -| | Test utilities | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/integration/package-summary.html}integration}} | Integration tests. | -*-------*-----------------*--------*--------------* -|| <> | Sample application | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/examples/webapp/package-summary.html}webapp}} | A sample web application. | -*-------*-----------------*--------*--------------* -| | Sample application | {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/examples/cli/package-summary.html}cli}} | A sample CLI application. | -*-------*-----------------*--------*--------------* + These libraries aim to make two parts of Solid easier to work with: {{{./session-management.html}Authorization}} and {{{./data-modeling.html}Data Mapping}}. -* Inrupt's Java Client modules and layers + Authorization is complicated, especially in a distributed ecosystem, such as Solid. These libraries provide flexibility while at the same time hiding much of the complexity of authorization. - Inrupt's Java Client Libraries are composed of different modules that follow a layered architectural approach. Next we will provide an overview of these layers and how to make use of them. - Make sure to visit the {{{./apidocs/}Documentation}} part for a javadoc style documentation with code examples for each module. - -** Interface Layer - - The {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/package-summary.html}api module}} is an interface module used in mostly all following modules. The provided abstractions are implemented in higher level modules and can be used to plug in your own application specific implementations. - - There are several specific parts to the API module: - - * Classes and interfaces used by developers writing Solid apps. These form the {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/package-summary.html}standard api}} of the Inrupt Java Client Libraries. - - * Classes and interfaces used by developers extending HTTP, JSON or RDF functionalities. These interfaces comprise the {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/spi/package-summary.html}spi}} package and will be used for implementing support for a new RDF processor, JSON processor or HTTP client library. - - * Classes and interfaces used by developers extending authentication functionalities. These interfaces comprise the {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/auth/package-summary.html}auth}} package and are helpful for authentication and authorization. - -** Core Modules Layer - - The next listed modules make up what we call the core modules layer of the Java Client Libraries. See these modules as basic building blocks on top of which further Solid and then application specific implementations can be developed. - - * <> - - Authentication & authorization are processes part of verifying the identity of an agent. To access private data on Solid Pods, you must authenticate as a user/agent who has been granted appropriate access to that data. - - Inrupt's Java Client Libraries provide different layers of abstraction to be used when needing authentication and authorization. Low level modules include OpenID and UMA. - - * OpenID - - The {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/openid/package-summary.html}openid module}} builds on top of the {{{https://openid.net/specs/openid-connect-core-1_0.html}OpenID Connect}} standards, which itself builds on the {{{https://datatracker.ietf.org/doc/html/rfc6749}OAuth 2.0}} authorization framework. - - * UMA - - The {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/uma/package-summary.html}uma module}} builds on top of the {{{https://docs.kantarainitiative.org/uma/wg/rec-oauth-uma-grant-2.0.html}UMA}} specification. - - Remark: Higher level abstractions that help with authentication and authorization are part of the {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/core/package-summary.html}core module}}. This module includes classes such as <<>> which encapsulates a reactive authentication approach. This class makes use of the basic authentication and authorization modules to automatically determine the preferred authentication and authorization the server needs and then negotiate the according tokens and access. See {{{https://inrupt.github.io/solid-client-java/gettingStarted.html}Getting Started}} for how to use the <<>>. - - * <> - - For interacting with a Solid server through an HTTP client there are two low level modules available: the java.net {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/httpclient/package-summary.html}HttpClient}} or the {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/okhttp/package-summary.html}OkHttp}}. - - * HttpClient - - This module build on top of the {{{https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/package-summary.html}java.net.http.HttpClient}}. - For example code and usage visit the javadoc at the {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/httpclient/package-summary.html}httpclient module}}. - - * OkHttp - - This module builds on top of the {{{https://square.github.io/okhttp/}OkHttp}} client. - For example code and usage visit the javadoc at the {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/okhttp/package-summary.html}okhttp module}}. - - * <> - - * RDF4J - - {{{https://rdf4j.org/documentation/}RDF4J}} is one of the widely known RDF processing libraries for Java. - For example code and usage visit the javadoc at the {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/rdf4j/package-summary.html}rdf4j module}}. - - * Jena - - {{{https://jena.apache.org/documentation/javadoc.html}Jena}} is one of the widely known RDF processing libraries for Java. - For example code and usage visit the javadoc at the {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/jena/package-summary.html}jena module}}. - - * <> - - * JSON-B - - {{{https://javaee.github.io/jsonb-spec/getting-started.html}JSON-B}} is providing a Java API for JSON Bindings. - Visit the {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/jsonb/package-summary.html}jsonb module}} javadocs for examples of how to make use of it in Inrupt's Java Client Libraries. - - * Jackson - - {{{https://github.com/FasterXML/jackson}Jackson}} is the Java JSON library that helps you parse and work with JSON. - Visit the {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/jackson/package-summary.html}jackson module}} javadocs for examples of how to make use of it in Inrupt's Java Client Libraries. - -** Domain-specific Modules Layer - - * <> - - The {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/core/package-summary.html}core module}} provides implementations of all API interfaces. Among which, a client implementation for use with Solid resources, <<>>. - - * <> - - The {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/solid/package-summary.html}solid module}} provides handlers for Solid resources and containers. - - * <> - - The {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/webid/package-summary.html}webid module}} provides a handler for working with the Solid WebId profile document. + Beyond authorization, working with RDF is also complicated. A graph-based data model may not be as familiar as the tree-based structures of JSON and XML. Furthermore, the tooling for RDF tends also to be less familiar. These libraries aim to give RDF experts all the features they need, while also being easy to use for newcomers to RDF. diff --git a/src/site/apt/session-management.apt.vm b/src/site/apt/session-management.apt.vm new file mode 100644 index 00000000000..683d74ec904 --- /dev/null +++ b/src/site/apt/session-management.apt.vm @@ -0,0 +1,195 @@ +Session Management + + All authentication and authorization in the Inrupt Java Client Libraries occur in the context of a <<>> object. By default, all client interactions use an anonymous session. For any interaction with non-public resources, you will need a mechanism for authenticating users. This guide will help you determine how best to create and manage these sessions in your Solid application. + +* What you will need + + * About 15 minutes + + * Your favorite text editor or IDE + + * Java 11 or later + + * Maven 3.5 or later + +* How to complete + + The first step is to consider how users will interact with your application. + + * Will this application run as a Web Application with many different users logging in? If so, follow the steps for {{Web Applications}}. + + * Will this application run from the Command Line with a single user? If so, follow the steps for {{Command Line Applications}}. + + + There are other, more advanced options possible, but these will be the two most common patterns. Furthermore, both patterns also support the use of Access Grants, which is described in the {{Using Access Grants}} section. + + After deciding how to establish a <<>>, you will pass that value to your client to create a Session-constrained client, as described in {{Using Session objects with a Client}}. + + If you are using Solid {{Access Grants}}, please refer to that section for more information. + + Finally, you can move on to the {{{./data-modeling.html}data modeling}} section, which describes how to bind Java objects to RDF resources. + +* Web Applications + + A very common pattern for building Solid apps involves operating them as Web Applications in which different users are able to login with a Web Browser. + + Most Java-based Web Applications will use a framework, such as {{{https://spring.io/}Spring Boot}}, {{{https://quarkus.io/}Quarkus}} + or {{{https://micronaut.io/}Micronaut}}. Each of these frameworks already provides an OpenID Connect Authentication integration. These frameworks + will expect a <<>> value and the URL of an authorization server. There will typically be other configuration properties, but this guide focuses + on these two values. + + If you are using Inrupt's Open ID Provider, the authorization server URL will be <<>>. + + For the <<>>, you will use a "public client", which does not need authentication. For this, you can either create your own + "Client Identifier document", and make this available in a public location on the Web. Ensure that the URL of this resource is exactly + the same as the <<>> property of document. Below is an example of a Client Identifier document. + ++--- +{ + "@context": [ + "https://www.w3.org/ns/solid/oidc-context.jsonld" + ], + "client_id": "https://application.example/identifier.jsonld", + "client_name": "My First Solid Application", + "client_uri": "https://application.example/", + "redirect_uris": [ + "https://application.example/callback" + ], + "post_logout_redirect_uris": [ + "https://application.example/" + ] +} ++--- + + Alternatively, if you plan to run your application at <<>> you can use a special Client Id + for testing at <<>>. + + For this example, assume that your application will run at the URL <<>> (and for development at <<>>) + + Using the OpenID Connect extension for the relevant framework, it will be possible to get a raw ID Token. This is all that is needed by + the Inrupt Java Client. In particular, the <<>> method will be used in this scenario. + + For Example, with Quarkus, your code might look like this: + ++--- +@ApplicationScoped +public class MyEndpoint { + + @Inject + @IdToken + JsonWebToken idToken; + + @GET + @Path("/") + public MyDataResource fetch() { + Session session = OpenIdSession.ofIdToken(idToken.getRawToken()); + ... + } +} ++--- + + With Spring Boot, your code might look like this: + ++--- +@RestController +public class Endpoint { + + @GetMapping("/") + public MyDataResource fetch(@AuthenticationPrincipal OidcUser principal) { + Session session = OpenIdSession.ofIdToken(principal.getIdToken().getTokenValue()); + ... + } + +} ++--- + + In both cases, a <<>> object is created by passing the value of the OpenID Connect ID Token to + the <<>> method. + + +* Command Line Applications + + Command-line applications will typically operate on behalf of a single user. For this type of interaction, + you will need to establish a "client credential" using a few pieces of information that are retrieved from + an identity provider such as the Application Registration page on + {{{https://login.inrupt.com/registration.html}Inrupt's OpenID Provider}}. After logging in, you can register + a new app or use an existing one. + + In this case, there are two pieces of information to note: + + * <<>> + + * <<>> + + In addition, you will need an <<>> value, which in this case is <<>> + and an <<>>, which will be <<>>. + + Building a session with this information will make use of the <<>> method as in the following example. + ++--- +public class MyApplication { + + public void run() { + URI issuer = URI.create("https://login.inrupt.com"); + Session session = OpenIdSession.ofClientCredentials(issuer, "", "", "client_secret_basic"); + ... + } +} ++--- + +* Using Session objects with a Client + + In order to create a Session-scoped client, use the <<<::session(Session)>>> method with the client of your choice. + + <>: all subsequent interactions should use the client value. Each client object is stateless: + calling the <<>> method will not change the original client. + ++--- +public class MyApplication { + + SolidSyncClient client; + + void init() { + Session session = ...; + client = SolidSyncClient.getClient().session(session); + } +} ++--- + + +* Access Grants + + {{{https://docs.inrupt.com/ess/latest/security/access-requests-grants/}Access Grants}} provide an alternative way to give access to your Solid resources. The Inrupt Java Client Libraries + provide tooling for working with Access Grants. + + Access Grant-based sessions are more complicated than OpenId-based sessions in that an Access Grant session requires an OpenId session. This is best illustrated with an example: + ++--- +public class MyApplication { + + SolidSyncClient client; + + void init() throws IOException { + try (InputStream grant = MyApplication.class.getResourceAsStream("/access-grant.json")) { + // Parse Access Grant + AccessGrant accessGrant = AccessGrant.ofAccessGrant(grant); + + // Set up OpenId Session + Session openid = OpenIdSession.ofClientCredentials(issuer, clientId, clientSecret, authMethod); + + // Set up Access Grant Session + Session session = AccessGrantSession.ofAccessGrant(openid, accessGrant); + + client = SolidSyncClient.getClient().session(session); + } + } +} ++--- + + In this case, if you have an existing Access Grant, you can create a <<>> that uses an OpenID-based session with these Access Grants. + + +* Next Steps + + If you are using one of the high-level clients and you have a working <<>> object, you can move on to the {{{./data-modeling.html}data modeling}} section, which describes how to bind Java objects to RDF resources. + diff --git a/src/site/apt/setUp.apt.vm b/src/site/apt/setUp.apt.vm deleted file mode 100644 index 0d9c251592f..00000000000 --- a/src/site/apt/setUp.apt.vm +++ /dev/null @@ -1,89 +0,0 @@ -Set Up - - The Inrupt Java Client Libraries are available on {{{https://search.maven.org/}Maven Central}}. - The easiest way to get started involves adding the Inrupt Java Client Libraries BOM to your project's POM by adding the following: - ----------------------- - - - - com.inrupt - inrupt-client-bom - ${inrupt.client.version} - - - ----------------------- - - Next, decide which modules are added to your own project's POM for dedicated functionalities. For details on each module, please check the table in the {{{https://inrupt.github.io/solid-client-java/}Home}} page. - -* Selectively installing modules - - The core layer modules offer duplicate functionalities because they make use of different underlying libraries. You will have to choose which exact libraries you want to make use of and add its according module. If one adds both modules, for the HTTP client for example, it is not guaranteed which exact one is going to be loaded first from the classpath. - Choices can be made for the HTTP service, JSON and RDF processing. The following choices are available: - -*-------------------------*---------------------*---------------------* -|| HTTP | <> | <> | -*-------------------------*----------------------*-----------------------* -| inrupt-client-httpclient | inrupt-client-jena | inrupt-client-jackson | -*--------------------------*---------------------*-----------------------* -| inrupt-client-okhttp | inrupt-client-rdf4j | inrupt-client-jsonb | -*--------------------------*---------------------*-----------------------* - -** Authentication - - Select any number of authentication providers: - -*----------------------* -|| Authentication | -*----------------------* -| inrupt-client-openid | -*----------------------* -| inrupt-client-uma | -*----------------------* - -** Domain-specific modules - - Once the core layer modules have been selected, it is optional if one wants to add further domain-specific layer modules such as solid or webid. - The domain-specific layer modules expose further abstractions on how to directly work with solid concepts. These functionalities can be implemented also through the core modules by working directly with the available libraries (RDF4J or JENA and so on), or one can create their own domain-specific abstractions. - -*----------------------* -|| Domain modules | -*----------------------* -| inrupt-client-webid | -*----------------------* -| inrupt-client-solid | -*----------------------* - -** Example - ----------------------- - - com.inrupt - inrupt-client-solid - - - com.inrupt - inrupt-client-jena - - - com.inrupt - inrupt-client-httpclient - - - com.inrupt - inrupt-client-jackson - - - com.inrupt - inrupt-client-openid - ----------------------- - -* Developing own domain-specific abstractions - - The {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/package-summary.html}api module}} of the Java Client Libraries uses the Service Provider Interface to make use of dedicated implementations loaded on the classpath. While the core layer offers options for HTTP client, RDF and JSON processing, one can also add own such implementations. - - For example, to make use of another HTTP client, the new class needs to implement the HttpService interface available from the api module. Make sure not to load any other <<>> module on the classpath and the new HTTP client implementation will be loaded by the Service Provider instead. The same applies for JSON and RDF processing as well. - - Authentication and authorization also make use of the Service Provider Interface. There is a dedicated <<>> and a <<>> which extend the <<>> interface. Furthermore, the {{{https://inrupt.github.io/solid-client-java/apidocs/com/inrupt/client/auth/package-summary.html}auth api module}} interfaces can further assist with authentication and authorization concepts. \ No newline at end of file diff --git a/src/site/apt/usage-examples.apt.vm b/src/site/apt/usage-examples.apt.vm new file mode 100644 index 00000000000..1898e0ddf20 --- /dev/null +++ b/src/site/apt/usage-examples.apt.vm @@ -0,0 +1,138 @@ +Usage Examples + + An application can obtain a client for interacting with Solid data in several ways. This guide will help you decide how your application will retrieve, configure and use a client. + +* What you will need + + * About 15 minutes + + * Your favorite text editor or IDE + + * Java 11 or later + + * Maven 3.5 or later + +* How to complete + + The first step is to decide which client is appropriate for your application. + + After deciding which client to use, the next step is to consider how you plan to {{{./session-management.html}manage authenticated sessions}}. + +* Client Options + + There are three types of clients available for use, each with the following characteristics: + + * {{<>}}. This client simplifies the basic Create-Read-Update-Delete operations you would expect in a RESTful client, while supporting a data binding mechanism between Java objects and Solid resources. + + * {{<>}}. This client is exactly like the synchronous client except that all responses are wrapped in a <<>>>. + + * {{<>}}. This client is considerably more verbose and gives developers full control over the HTTP requests and responses. + + + For the low-level client, there is a single method to perform an HTTP operation: <<>>. + + For the high-level clients, in addition to the low-level <<<::send>>> API, you will have several other methods available: + + * <<<\ ::create(T)>>> -- given an object that is a subclass of <<>>, create a new Solid resource. + + * <<<\ ::read(URI, Class)>>> -- fetch a Solid resource from a known URI and marshall it into the given type. + + * <<<\ ::update(T)>>> -- given an object that is a subclass of <<>>, update an existing Solid resource. + + * <<<\ ::delete(T)>>> -- given an object that is a subclass of <<>>, delete the corresponding Solid resource. + + +* High-Level Synchronous Client + + The high-level synchronous client, offers a RESTful API, allowing for synchronous interaction with Solid resources. In addition this client manages a data binding between the Java types you define and the underlying Solid resources. + +** Simple example + ++---------------- +public class ClientSample { + + public void useTheHighLevelSyncClient() { + SolidSyncClient client = SolidSyncClient.getClient(); + + URI uri = URI.create("https://storage.example/resource.ttl"); + SolidResource resource = client.read(uri, SolidResource.class); + } +} ++---------------- + +* High-Level Asynchronous Client + + The high-level asynchronous client API is exactly like the synchronous API, except that the return types are wrapped in a <<>>>. + +** Simple example + ++---------------- +public class ClientSample { + + public CompletionStage useTheHighLevelAsyncClient() { + SolidClient client = SolidClient.getClient(); + + URI uri = URI.create("https://storage.example/resource.ttl"); + return client.read(uri, SolidResource.class); + } +} ++---------------- + +* Low-Level Client + + The low-level client API gives developers full control over HTTP requests and responses. This API is also considerably more verbose, while only including a single method: <<<::send>>>. + +** Simple example + ++--------------- +public class ClientSample { + + public CompletionStage useTheLowLevelClient() { + Client client = ClientProvider.getClient(); + + URI uri = URI.create("https://storage.example/resource.ttl"); + Request req = Request.newBuilder(uri) + .header("Accept", "text/turtle") + .GET() + .build(); + + return client.send(req, Response.BodyHandlers.ofInputStream()).thenAccept(res -> { + if (res.statusCode() == 200) { + return res.body(); + } + return "Error accessing resource: " + res.statusCode(); + }); + } +} ++--------------- + +** Request Body Publishers + + Write operations such as <<>> and <<>> will typically contain a request body. The low-level client provides a number of request body publishers for use by developers. These publishers make it easier to translate existing Java objects into HTTP requests. Some existing body publishers include: + + * <<>> This publisher accepts a <<>> and will convert that into an HTTP request body. + + * <<>> This publisher accepts an <<>>. + + * <<>> This publisher uses an empty body in the HTTP request. + + In addition, when working directly with RDF resources, there are Jena and RDF4J publishers that will serialize an RDF Model as an HTTP request. These handlers are useful in cases where applications are already using an RDF framework. In these cases, <<>> or <<>> would be used. + + +** Response Body Handlers + + The low-level client also provides a number of response body handlers for use by developers. The following body handlers are always available: + + * <<>> This handler discards any response content. It is especially useful for write operations such as <<>>, <<>> and <<>>. + + * <<>> This handler maps the HTTP response to an <<>>. This may be useful for custom processing of the response body. + + * <<>> This handler maps the HTTP response to a <<>>. This may be useful for small text-oriented responses, though one should generally prefer the <<>>-based API. + + + When working with RDF resources, there are Jena and RDF4J handlers that will map HTTP responses directly to a Jena or RDF4J Model. These handlers are useful in cases where applications are already using an RDF framework. <<>> or <<>> would be used in these cases. + +* Next Steps + + Now that you have decided which client to use, the next step is to consider how to {{{./session-management.html}manage authenticated sessions}}. + diff --git a/src/site/site.xml b/src/site/site.xml index c4c8254888b..8b27abb0e18 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -9,8 +9,10 @@ - - + + + + From 2a2ada96cfe7742fda603ecd8c2897c3c48c6bc7 Mon Sep 17 00:00:00 2001 From: Aaron Coburn Date: Fri, 3 Mar 2023 08:58:11 -0500 Subject: [PATCH 2/4] Apply suggestions from code review Co-authored-by: Timea <4144203+timea-solid@users.noreply.github.com> --- src/site/apt/data-modeling.apt.vm | 6 +++--- src/site/apt/session-management.apt.vm | 12 +++++------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/site/apt/data-modeling.apt.vm b/src/site/apt/data-modeling.apt.vm index e2f92ded0fa..f883880bbcb 100644 --- a/src/site/apt/data-modeling.apt.vm +++ b/src/site/apt/data-modeling.apt.vm @@ -12,15 +12,15 @@ Data Modeling * Maven 3.5 or later -* Solution +* How to complete The solution involves creating a wrapper class so that your class can act not only as an RDF Graph but also as a domain-specific type. * 1. Subclass the Resource type - The first step involves ensuring that your class extends the <<>> class - and consider the methods you expect in your class. + The first step involves ensuring that your class extends the <<>> class. + Afterwards, consider the methods you expect in your class. +--- public class Playlist extends Resource { diff --git a/src/site/apt/session-management.apt.vm b/src/site/apt/session-management.apt.vm index 683d74ec904..23a784e84a5 100644 --- a/src/site/apt/session-management.apt.vm +++ b/src/site/apt/session-management.apt.vm @@ -41,8 +41,8 @@ Session Management If you are using Inrupt's Open ID Provider, the authorization server URL will be <<>>. For the <<>>, you will use a "public client", which does not need authentication. For this, you can either create your own - "Client Identifier document", and make this available in a public location on the Web. Ensure that the URL of this resource is exactly - the same as the <<>> property of document. Below is an example of a Client Identifier document. + "{{{https://solidproject.org/TR/oidc#clientids-document}Client Identifier document}}", and make this available in a public location on the Web. Ensure that the URL of this resource is exactly + the same as the <<>> property of the document. Below is an example of a Client Identifier document. +--- { @@ -66,10 +66,10 @@ Session Management For this example, assume that your application will run at the URL <<>> (and for development at <<>>) - Using the OpenID Connect extension for the relevant framework, it will be possible to get a raw ID Token. This is all that is needed by + Using the {{{https://openid.net/connect/}OpenID Connect}} extension for the relevant framework, it will be possible to get a raw ID Token. This is all that is needed by the Inrupt Java Client. In particular, the <<>> method will be used in this scenario. - For Example, with Quarkus, your code might look like this: + For example, with Quarkus, your code might look like this: +--- @ApplicationScoped @@ -112,10 +112,8 @@ public class Endpoint { Command-line applications will typically operate on behalf of a single user. For this type of interaction, you will need to establish a "client credential" using a few pieces of information that are retrieved from an identity provider such as the Application Registration page on - {{{https://login.inrupt.com/registration.html}Inrupt's OpenID Provider}}. After logging in, you can register - a new app or use an existing one. + {{{https://login.inrupt.com/registration.html}Inrupt's OpenID Provider}}. After logging in to the identity provider, you can register a new application and in turn, get: - In this case, there are two pieces of information to note: * <<>> From a571316ca5af428ce731d2f177725ef5253ae170 Mon Sep 17 00:00:00 2001 From: Aaron Coburn Date: Fri, 3 Mar 2023 08:58:54 -0500 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: Timea <4144203+timea-solid@users.noreply.github.com> --- src/site/apt/getting-started.apt.vm | 2 +- src/site/apt/index.apt.vm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/site/apt/getting-started.apt.vm b/src/site/apt/getting-started.apt.vm index 591c4d84d9b..e530c000a03 100644 --- a/src/site/apt/getting-started.apt.vm +++ b/src/site/apt/getting-started.apt.vm @@ -1,6 +1,6 @@ Getting Started With Inrupt's Java Client Libraries - This guide will help you set up Java project using Maven. This project will contain all the necessary components to begin building a Solid application in Java. + This guide will help you set up a Java project using Maven. The project contains all the necessary components to begin building a Solid application. * What you will need diff --git a/src/site/apt/index.apt.vm b/src/site/apt/index.apt.vm index a1b8b913dbe..5f9b0786216 100644 --- a/src/site/apt/index.apt.vm +++ b/src/site/apt/index.apt.vm @@ -2,7 +2,7 @@ Inrupt's Java Client Libraries {{{https://inrupt.com}Inrupt}} provides the following Java client libraries to help developers create {{{https://solidproject.org}Solid}} applications. These libraries provide highly flexible, simple components that can be used in any Java application for {{{https://solidproject.org/TR/protocol}Solid}}. - These libraries aim to make two parts of Solid easier to work with: {{{./session-management.html}Authorization}} and {{{./data-modeling.html}Data Mapping}}. + These libraries aim to make two parts of Solid easier to work with: {{{./session-management.html}Authorization}} and {{{./data-modeling.html}Data Modeling}}. Authorization is complicated, especially in a distributed ecosystem, such as Solid. These libraries provide flexibility while at the same time hiding much of the complexity of authorization. From 86b6a9e93611d59e06044512e84d0f4a7aabf22d Mon Sep 17 00:00:00 2001 From: Aaron Coburn Date: Fri, 3 Mar 2023 10:15:21 -0500 Subject: [PATCH 4/4] Additional information for data modeling --- src/site/apt/data-modeling.apt.vm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/site/apt/data-modeling.apt.vm b/src/site/apt/data-modeling.apt.vm index f883880bbcb..50e859795fc 100644 --- a/src/site/apt/data-modeling.apt.vm +++ b/src/site/apt/data-modeling.apt.vm @@ -84,6 +84,13 @@ public class Playlist extends Resource { } +--- + Your inner class (<<>> in this example) will have access to a variety of functions + to aid in mapping between the underlying RDF Graph and your Java type. {{{https://javadoc.io/doc/com.inrupt/inrupt-rdf-wrapping-commons/latest/com/inrupt/rdf/wrapping/commons/WrapperBlankNodeOrIRI.html}These methods}} are summarized in the <<>> Javadocs. + + Similarly, the built-in {{{https://javadoc.io/doc/com.inrupt/inrupt-rdf-wrapping-commons/latest/com/inrupt/rdf/wrapping/commons/TermMappings.html}TermMappings}} + and {{{https://javadoc.io/doc/com.inrupt/inrupt-rdf-wrapping-commons/latest/com/inrupt/rdf/wrapping/commons/ValueMappings.html}ValueMappings}} + are described in the {{{https://javadoc.io/doc/com.inrupt/inrupt-rdf-wrapping-commons/latest/com/inrupt/rdf/wrapping/commons/package-summary.html}Javadocs}} for the <<>> library. + * 3. Connect your public methods to the wrapper node Now you are ready to link your public methods to the methods from your inner class.