Skip to content

invopop/phive

Repository files navigation

Phive gRPC Service

A gRPC wrapper for phive (Philip Helger Integrative Validation Engine) that validates XML documents against e-invoicing standards.

Built using the phive and phive-rules libraries by @phax.

What it does

  • List VESIDs: Get all available validation rule sets
  • Validate XML: Validate invoices and documents against standards like Peppol, EN 16931, XRechnung, UBL, CII, and more

Note: Many validation sets are marked as deprecated - filter by status: "valid" to get current rule sets.

Quick Start

Using Docker

# Start the service
docker run -d -p 9090:9090 invopop/phive-grpc-service

Using Go

Import the protocol package directly:

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"

	"github.com/invopop/phive"
)

func main() {
	// Create gRPC connection
	conn, err := grpc.NewClient(
		"localhost:9090",
		grpc.WithTransportCredentials(insecure.NewCredentials()),
	)
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	client := phive.NewValidationServiceClient(conn)
	ctx := context.Background()

	// List validation rule sets
	resp, err := client.ListVesIds(ctx, &phive.ListVesIdsRequest{
		Filter: "peppol",
	})
	if err != nil {
		log.Fatal(err)
	}

	for _, vesid := range resp.Vesids {
		if vesid.Status == "valid" {
			fmt.Printf("%s: %s\n", vesid.Vesid, vesid.Name)
		}
	}

	// Validate XML
	xmlContent, err := os.ReadFile("invoice.xml")
	if err != nil {
		log.Fatal(err)
	}

	result, err := client.ValidateXml(ctx, &phive.ValidateXmlRequest{
		Vesid:            "eu.peppol.bis3:invoice:2024.5",
		XmlContent:       xmlContent,
		SourceIdentifier: "my-invoice-id",
	})
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Valid: %v\n", result.Success)
}

Using grpcurl

The service has gRPC reflection enabled, so you don't need proto files:

# List all available validation rule sets
grpcurl -plaintext \
  -d '{"filter":""}' \
  localhost:9090 invopop.phive.v1.ValidationService/ListVesIds

# Filter by keyword
grpcurl -plaintext \
  -d '{"filter":"peppol"}' \
  localhost:9090 invopop.phive.v1.ValidationService/ListVesIds

# Validate XML (use -w 0 to prevent newlines in base64 output)
grpcurl -plaintext \
  -d '{
    "vesid": "un.unece.uncefact:crossindustryinvoice:D22B",
    "xml_content": "'$(base64 -w 0 < invoice.xml)'"
  }' \
  localhost:9090 invopop.phive.v1.ValidationService/ValidateXml

# List all available services (uses reflection)
grpcurl -plaintext localhost:9090 list

# Describe the ValidationService
grpcurl -plaintext localhost:9090 describe invopop.phive.v1.ValidationService

API

Service: invopop.phive.v1.ValidationService

ListVesIds

Get available validation rule sets with optional filtering.

Request:

{
  "filter": "peppol"  // optional keyword filter
}

Response:

{
  "vesids": [
    {
      "vesid": "eu.peppol.bis3:invoice:2024.5",
      "name": "OpenPeppol Invoice (2024.5)",
      "version": "2024.5",
      "status": "valid"
    }
  ]
}

ValidateXml

Validate an XML document against a specific VESID.

Request:

{
  "vesid": "eu.peppol.bis3:invoice:2024.5",
  "xml_content": "<base64-encoded-xml>",
  "source_identifier": "optional-doc-id"
}

Response:

{
  "success": true,
  "resolved_vesid": "eu.peppol.bis3:invoice:2024.5",
  "timestamp": "2025-01-17T23:38:59Z",
  "results": [
    {
      "validation_type": "XSD",
      "artifact_id": "path/to/schema.xsd",
      "success": true,
      "errors": [],
      "warnings": []
    }
  ]
}

gRPC Reflection

This service has gRPC reflection enabled, making it easy to explore and test the API without proto files.

Benefits

  • Use grpcurl without managing proto files
  • Explore available methods and messages dynamically
  • Perfect for testing and development in private clusters

Protocol Files

The proto definition and generated Go files are at the root:

  • validation.proto - Protocol definition
  • validation.pb.go - Protocol buffer messages
  • validation_grpc.pb.go - gRPC service definitions

To regenerate the Go files:

protoc --go_out=. --go_opt=paths=source_relative \
  --go-grpc_out=. --go-grpc_opt=paths=source_relative \
  validation.proto

Note: Reflection is enabled because this service runs in private clusters. For public internet-facing deployments, consider disabling it by removing ProtoReflectionService from the server builder.

Building

# Build with Maven
mvn clean package

# Build Docker image
docker build -t phive-grpc-service .

Configuration

Set environment variables:

  • GRPC_SERVER_PORT: gRPC server port (default: 9090)
  • JAVA_OPTS: JVM options (default: -Xms256m -Xmx1024m)

Included Validation Rules

  • Peppol BIS 3 - Peppol Business Interoperability Specifications
  • EN 16931 - European e-invoicing standard
  • XRechnung - German e-invoicing
  • UBL - Universal Business Language (all versions)
  • CII - Cross Industry Invoice (D16B, D22B)
  • FacturaE - Spanish e-invoicing
  • FatturaPA - Italian e-invoicing
  • ZUGFeRD - German e-invoicing format
  • Factur-X - French pdf+xml e-invoicing
  • France-CTC - French e-invoicing

Many rule sets are deprecated so you may need to filter by status on your end.

See phive-rules for the complete list.

License

Apache License 2.0

Links

About

A simple gRPC wrapper for phive

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors