Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c94352f
fixing checkstyle issues, configuring pom to run checkstyle:check
markiantorno Jul 31, 2025
228674c
changing checks to run CHECKSTYLE over all modules
markiantorno Jul 31, 2025
191835d
checkstyle now runs on every PR across every module, and fails fast
markiantorno Jul 31, 2025
ae18caa
Merge branch 'hapifhir:master' into master
markiantorno Jul 31, 2025
1ceafe2
checkstyle profile now unified instead of having a checkstyle and che…
markiantorno Jul 31, 2025
bf5ae1c
need to build checkstyle first
markiantorno Jul 31, 2025
45164b0
need to move checkstyle to after the cache build job
markiantorno Jul 31, 2025
672244b
applying spotless changes
markiantorno Jul 31, 2025
24110e0
checkstyle will not block pipeline from running
markiantorno Jul 31, 2025
a6470b4
checkstyle now a reusable action
markiantorno Jul 31, 2025
eff0292
adding debug
markiantorno Jul 31, 2025
3c002ab
The pipeline should now work correctly because Maven will find the c…
markiantorno Jul 31, 2025
a884757
moving to local branch to test caching
markiantorno Aug 1, 2025
8b2332c
wip
markiantorno Aug 1, 2025
5dd53a8
wip
markiantorno Aug 7, 2025
d2913dd
wip
markiantorno Aug 8, 2025
5dd2efa
Merge pull request #2 from markiantorno/actions_temp
markiantorno Aug 8, 2025
8d3af98
Merge branch 'hapifhir:master' into master
markiantorno Aug 8, 2025
3f3e7d2
fixing r4 test
markiantorno Aug 8, 2025
2fca433
Merge pull request #3 from markiantorno/actions_temp
markiantorno Aug 8, 2025
7d2f62d
test fix error code
markiantorno Aug 11, 2025
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
2 changes: 1 addition & 1 deletion .github/actions/build-cache/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ runs:
MAVEN_CACHE_FOLDER: ${{ inputs.cache-path }}
MAVEN_OPTS: '-Xmx1024m -Dorg.slf4j.simpleLogger.showDateTime=true -Dorg.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss,SSS -Duser.timezone=America/Toronto'
run: |
mvn clean install -P CI,CHECKSTYLE \
mvn clean install -P CI \
-Dmaven.test.skip=true -e -B \
-Dmaven.javadoc.skip=true \
-Dmaven.wagon.http.pool=false \
Expand Down
64 changes: 64 additions & 0 deletions .github/actions/checkstyle-validation/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: 'Cross-Module Checkstyle Validation'
description: 'Runs cross-module checkstyle validation to detect duplicate error codes and other violations'

inputs:
java-version:
description: 'The Java version to use'
required: false
default: '17'
maven-cache-key:
description: 'The cache key for Maven dependencies'
required: true
hapi-cache-key:
description: 'The cache key for HAPI dependencies'
required: true

runs:
using: "composite"
steps:
- name: Create and List Maven Cache Directory
shell: bash
run: |
mkdir -p $HOME/.m2/repository
pwd
ls -al $HOME/.m2/repository
env:
MAVEN_CACHE_FOLDER: $HOME/.m2/repository

- name: Restore HAPI Cache
uses: ./.github/actions/caching-handler
with:
path: "$HOME/.m2/repository/ca/uhn/"
key: ${{ inputs.hapi-cache-key }}

- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: ${{ inputs.java-version }}
cache: 'maven'

- name: Restore Maven Cache
uses: ./.github/actions/caching-handler
with:
key: ${{ inputs.maven-cache-key }}

- name: Debug cache contents
shell: bash
run: |
echo "Checking Maven repository contents..."
ls -la $HOME/.m2/repository/ca/uhn/hapi/fhir/ || echo "HAPI FHIR directory not found"
ls -la $HOME/.m2/repository/ca/uhn/hapi/fhir/hapi-fhir-checkstyle/ || echo "hapi-fhir-checkstyle directory not found"
find $HOME/.m2/repository -name "*checkstyle*" -type f || echo "No checkstyle artifacts found"

- name: Run cross-module checkstyle validation
shell: bash
env:
MAVEN_CACHE_FOLDER: $HOME/.m2/repository
run: |
echo "Running cross-module checkstyle validation to detect duplicate error codes and other violations..."
echo "This step ensures that HAPI FHIR error codes (Msg.code) are unique across all modules."
echo "If this step fails, it means there are checkstyle violations that must be fixed before the build can proceed."
echo ""
mvn validate -P CHECKSTYLE --batch-mode --no-transfer-progress \
-Dmaven.repo.local=$MAVEN_CACHE_FOLDER
19 changes: 18 additions & 1 deletion .github/workflows/parallel-pipeline-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,26 @@ jobs:
java-version: '17'
cache-path: $HOME/.m2/repository

checkstyle:
runs-on: ubuntu-latest
needs: build-cache
continue-on-error: true
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Run Checkstyle Validation
uses: ./.github/actions/checkstyle-validation
with:
java-version: '17'
maven-cache-key: ${{ github.ref_name }}-maven-${{ hashFiles('**/pom.xml') }}
hapi-cache-key: ${{ github.ref_name }}-hapi-${{ github.run_id }}

generate-module-list:
name: Generate List of Modules to Build
runs-on: ubuntu-latest
needs: checkstyle
if: always()
outputs:
modules_list: ${{ steps.format-modules.outputs.modules_list }}
steps:
Expand Down Expand Up @@ -94,7 +111,7 @@ jobs:
final-result:
if: ${{ always() }}
runs-on: ubuntu-latest
needs: [ assemble-test-reports ]
needs: [ assemble-test-reports, checkstyle ]
steps:
- run: exit 1
if: >-
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,6 @@ Snap.*
/database*/
/activemq-data/
/.run/
/CLAUDE.md
**/CLAUDE.md

**/.claude/settings.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
*/
package org.hl7.fhir.instance.model.api;

import ca.uhn.fhir.i18n.Msg;

public interface IBaseReference extends ICompositeType {

IBaseResource getResource();
Expand All @@ -38,7 +40,7 @@ default boolean hasIdentifier() {
}

default IBaseReference setIdentifier(ICompositeType theIdentifier) {
throw new UnsupportedOperationException("This reference does not support identifiers");
throw new UnsupportedOperationException(Msg.code(2759) + "This reference does not support identifiers");
}

default ICompositeType getIdentifier() {
Expand Down
34 changes: 0 additions & 34 deletions hapi-fhir-checkstyle/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -99,39 +99,5 @@
</plugins>
</build>
</profile>
<profile>
<id>CHECKSTYLE</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<excludes>**/osgi/**/*, **/.mvn/**/*, **/.mvn_/**/*</excludes>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
<!--suppress UnresolvedMavenProperty -->
<configLocation>checkstyle/hapi-base-checkstyle.xml</configLocation>
<!--suppress UnresolvedMavenProperty -->
<suppressionsLocation>checkstyle/hapi-base-checkstyle-suppression.xml</suppressionsLocation>
<inputEncoding>UTF-8</inputEncoding>
<consoleOutput>true</consoleOutput>
</configuration>
<executions>
<execution>
<id>checkstyle-across-all-modules</id>
<phase>install</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
<execution>
<id>hapi-single-module-checkstyle</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ private byte[] loadFileAsByteArray(String theFileName) throws ParseException {
input = IOUtils.toByteArray(new FileInputStream(new File(theFileName)));
} catch (IOException e) {
throw new ParseException(
Msg.code(1615) + "Failed to load file '" + theFileName + "' - Error: " + e.toString());
// Msg.code(1615) + "Failed to load file '" + theFileName + "' - Error: " + e.toString());
Msg.code(2478) + "Failed to load file '" + theFileName + "' - Error: " + e.toString());
}
return input;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,8 @@ private String encodeAsString(IBaseResource theResource) {
} else if (myDstu2Hl7OrgContext.getVersion().getVersion().equals(version)) {
return myDstu2Hl7OrgContext.newJsonParser().encodeResourceToString(theResource);
} else {
throw new IllegalArgumentException("Cannot encode resource with version: %s".formatted(version));
throw new IllegalArgumentException(
Msg.code(2777) + "Cannot encode resource with version: %s".formatted(version));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public void run() {

} catch (Exception theE) {
ourLog.error("Hibernate SQL log filters not refreshed. Exception: {} \n{}", theE, theE.getStackTrace());
throw new RuntimeException(Msg.code(2478) + theE);
throw new RuntimeException(Msg.code(2778) + theE);
} finally {
myRefreshDoneLatch.countDown();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/
package ca.uhn.fhir.jpa.cache;

import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.config.util.ResourceTypeUtil;
import ca.uhn.fhir.jpa.dao.data.IResourceTypeDao;
import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService;
Expand Down Expand Up @@ -119,7 +120,8 @@ protected ResourceTypeEntity createResourceType(String theResourceType) {
myResourceTypeDao.flush();
} catch (DataIntegrityViolationException e) {
if (e.getMessage().contains("Value too long for column")) {
throw new InternalErrorException("Resource type name is too long: " + theResourceType, e);
throw new InternalErrorException(
Msg.code(2764) + "Resource type name is too long: " + theResourceType, e);
}
// This can happen if the resource type already exists in the database
ourLog.info("Resource type already exists: {}", theResourceType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package ca.uhn.fhir.jpa.packages;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.BundleBuilder;
Expand All @@ -45,7 +46,7 @@ public static IBaseBundle bundleAdditionalResources(
try {
npmPackage = NpmPackage.fromPackage(new ByteArrayInputStream(packageInstallationSpec.getPackageContents()));
} catch (IOException e) {
throw new InternalErrorException(e);
throw new InternalErrorException(Msg.code(2765) + e);
}
List<IBaseResource> resources = getAdditionalResources(additionalResources, npmPackage, fhirContext);

Expand Down Expand Up @@ -73,15 +74,15 @@ public static List<IBaseResource> getAdditionalResources(
.flatMap(Collection::stream)
.collect(Collectors.toList());
} catch (IOException e) {
throw new InternalErrorException(e.getMessage(), e);
throw new InternalErrorException(Msg.code(2766) + e.getMessage(), e);
}

resources.addAll(fileNames.stream()
.map(fileName -> {
try {
return new String(folder.fetchFile(fileName));
} catch (IOException e) {
throw new InternalErrorException(e.getMessage(), e);
throw new InternalErrorException(Msg.code(2767) + e.getMessage(), e);
}
})
.map(parser::parseResource)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@ private Condition createPredicateSourceContains(JpaStorageSettings theStorageSet
String containsLikeExpression = createLeftAndRightMatchLikeExpression(normalizedString);
return BinaryCondition.like(upperFunction, generatePlaceholder(containsLikeExpression));
} else {
throw new MethodNotAllowedException(
Msg.code(getContainsModifierDisabledCode()) + ":contains modifier is disabled on this server");
throw new MethodNotAllowedException(Msg.code(2768) + ":contains modifier is disabled on this server");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.hl7.fhir.instance.model.api.IIdType;

import java.util.function.Supplier;
import javax.annotation.Nullable;

/**
* This is a request object containing a request to extract the FullText index data from
Expand All @@ -35,10 +34,10 @@
*/
public class FullTextExtractionRequest {

@Nullable
@Nonnull
private final IIdType myResourceId;

@Nullable
@Nonnull
private final IBaseResource myResource;

@Nonnull
Expand All @@ -51,8 +50,8 @@ public class FullTextExtractionRequest {
* Constructor
*/
public FullTextExtractionRequest(
@Nullable IIdType theResourceId,
@Nullable IBaseResource theResource,
@Nonnull IIdType theResourceId,
@Nonnull IBaseResource theResource,
@Nonnull String theResourceType,
@Nonnull Supplier<String> theDefaultSupplier) {
myResourceId = theResourceId;
Expand All @@ -71,15 +70,15 @@ public boolean isDelete() {
/**
* @return Returns the ID of the resource being indexed. This may be <code>null</code> if a new resource is being created, and a type isn't assigned yet
*/
@Nullable
@Nonnull
public IIdType getResourceId() {
return myResourceId;
}

/**
* @return Returns the resource being indexed. May be <code>null</code> if the operation is a resource deletion.
*/
@Nullable
@Nonnull
public IBaseResource getResource() {
return myResource;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
*/
package ca.uhn.fhir.jpa.searchparam.fulltext;

import javax.annotation.Nullable;
import jakarta.annotation.Nonnull;

/**
* This is a response object containing the FullText index data which should be stored during
Expand Down Expand Up @@ -72,7 +72,7 @@ public static FullTextExtractionResponse doNotIndex() {
*
* @param thePayload The fulltext payload string. May be <code>null</code> if no payload should be specified for the given resource.
*/
public static FullTextExtractionResponse indexPayload(@Nullable String thePayload) {
public static FullTextExtractionResponse indexPayload(@Nonnull String thePayload) {
return new FullTextExtractionResponse(false, false, thePayload);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void validate(IIdType theSubscriptionId, ResourceDeliveryMessage theResou
case OFF:
case NULL:
default:
throw new SubscriptionInactiveException(Msg.code(2668) + "Attempting to deliver "
throw new SubscriptionInactiveException(Msg.code(2762) + "Attempting to deliver "
+ theResourceDeliveryMessage.getPayloadId() + " to disabled subscription "
+ subscription.getIdElementString() + ". Aborting delivery.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ public void testSearchSource_withContainsModifierAndContainsSearchesDisabled_thr
myPatientDao.search(searchParameter);
fail();
} catch (MethodNotAllowedException e) {
assertEquals(Msg.code(2570) + ":contains modifier is disabled on this server", e.getMessage());
assertEquals(Msg.code(2768) + ":contains modifier is disabled on this server", e.getMessage());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ public void testReplaceAnElementInHighCardinalityField_NoMatchingElement_Invalid

//When: We apply the patch, expect an InvalidRequestException
InvalidRequestException ex = assertThrows(InvalidRequestException.class, () -> svc.apply(patient, patch));
String expectedMessage = String.format("HAPI-2617: No element matches the specified path: %s", thePath);
String expectedMessage = String.format("HAPI-2716: No element matches the specified path: %s", thePath);
assertThat(ex.getMessage()).isEqualTo(expectedMessage);

assertThat(patient.getIdentifier()).hasSize(2);
Expand Down
Loading
Loading