Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,26 @@ public RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTe
.build())
.build();

// DataCustodian resource-server introspection client. The DC resource server calls
// POST /oauth2/introspect with these credentials (client_secret_basic) to validate opaque
// tokens; any registered confidential client may introspect. Matches DC's default
// espi.authorization-server.client-id / client-secret (datacustodian / datacustodian-secret),
// so the local sandbox introspects out of the box.
RegisteredClient dataCustodianIntrospection = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("datacustodian")
.clientName("DataCustodian Introspection")
.clientSecret("{noop}datacustodian-secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.clientIdIssuedAt(Instant.now())
.clientSettings(ClientSettings.builder()
.requireAuthorizationConsent(false)
.build())
.build();

// Seed default clients, and reconcile existing ones to the code definition (see below).
initializeDefaultClients(repository, datacustodianAdmin, thirdPartyClient, thirdPartyAdmin);
initializeDefaultClients(repository, datacustodianAdmin, thirdPartyClient, thirdPartyAdmin,
dataCustodianIntrospection);

return repository;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ void shouldFindAllClientsCorrectly() {
List<String> allClientIds = registeredClientAdminDao.findAllClientIds();

// Then
assertThat(allClientIds).hasSize(5); // 2 test clients + 3 default clients
assertThat(allClientIds).hasSize(6); // 2 test clients + 4 default clients (incl. datacustodian introspection)
assertThat(allClientIds).contains("test-client-1", "test-client-2");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,8 @@ espi:
datacustodian:
base-url: http://localhost:8081/DataCustodian
authorization-server:
issuer-uri: http://localhost:8080
jwk-set-uri: http://localhost:8080/.well-known/jwks.json
# Local sandbox AS runs on :9999. Opaque-token introspection (ESPI standard) points here;
# client-id/secret default to datacustodian/datacustodian-secret (seeded on the AS).
issuer-uri: http://localhost:9999
introspection-endpoint: http://localhost:9999/oauth2/introspect
jwk-set-uri: http://localhost:9999/.well-known/jwks.json # unused (opaque tokens; no JWT/JWK)
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
*
* Copyright (c) 2025 Green Button Alliance, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.greenbuttonalliance.espi.thirdparty.config;

import jakarta.xml.bind.Marshaller;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;

import java.util.Map;

/**
* JAXB marshalling configuration for the Third Party.
*
* <p>Defines the {@code atomMarshaller} {@link Jaxb2Marshaller} that the resource-fetch layer
* (e.g. {@code ResourceRESTRepositoryImpl}) requires to (un)marshal ESPI Atom feeds/entries fetched
* from the Data Custodian. The bean was missing, so the TP context failed to start (#146); this
* supplies it, scanning the shared ESPI DTO (JAXB) packages — the same context the Data Custodian's
* marshaller uses.</p>
*/
@Configuration
public class JaxbMarshallingConfiguration {

@Bean(name = "atomMarshaller")
public Jaxb2Marshaller atomMarshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
// Domain entities carry no JAXB annotations (per the project's JPA/JAXB separation rule);
// the JAXB-annotated DTOs (incl. the Atom envelope DTOs) live under common.dto.
marshaller.setPackagesToScan(
"org.greenbuttonalliance.espi.common.domain",
"org.greenbuttonalliance.espi.common.dto");
marshaller.setMarshallerProperties(Map.of(
Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE,
Marshaller.JAXB_ENCODING, "UTF-8"));
return marshaller;
}
}
Loading