├── images ├── UpdateAlias_keytool.PNG ├── GetCertificate_info_keytool.PNG ├── SoapUI_altinn_example_Capture.JPG ├── Formidlingtjenesten_sekvensdiagram.jpg ├── Formidlingtjenesten_sekvensdiagram.png └── Windows_certificate_details_Capture.JPG ├── renovate.json ├── src ├── test │ ├── resources │ │ ├── LANGESUND_OG_MÅLØY_REGNSKAP.p12 │ │ ├── COMMFIDES_BAREKSTAD_OG_YTTERVÅG_REGNSKAP.p12 │ │ ├── Buypass_ID-KYSTBASEN_ÅGOTNES_OG_ILSENG_REGNSKAP.p12 │ │ ├── Buypass ID-LANGESUND OG MÅLØY REGNSKAP-serienummer2075247706312279234458841-2018-06-28.p12 │ │ ├── properties │ │ │ ├── formidling-tjeneste.xml │ │ │ ├── logging-properties.xml │ │ │ ├── avgiver-properties.xml │ │ │ ├── mottaker-properties.xml │ │ │ └── formidling-uri.xml │ │ ├── FormTask.xml │ │ └── wsdl │ │ │ ├── RegisterSRRAgencyExternalEC2.wsdl │ │ │ └── BrokerServiceExternalEC2Streamed.wsdl │ └── java │ │ └── no │ │ └── asf │ │ └── formidling │ │ └── client │ │ └── ws │ │ └── client │ │ ├── IntermediaryInboundTest.java │ │ ├── CorrespondenceTest.java │ │ ├── ReceiptEC2Test.java │ │ ├── FormidlingAvgiverTest.java │ │ └── FormidlingMottakerTest.java └── main │ ├── resources │ ├── properties │ │ ├── formidling-tjeneste.xml │ │ ├── logging-properties.xml │ │ └── formidling-uri.xml │ └── wsdl │ │ ├── RegisterSRRAgencyExternalEC2.wsdl │ │ ├── BrokerServiceExternalEC2Streamed.wsdl │ │ └── CorrespondenceExternalEC2.wsdl │ └── java │ └── no │ └── asf │ └── formidling │ └── client │ ├── ws │ ├── cookie │ │ └── CookieStore.java │ ├── interceptor │ │ ├── HeaderInterceptor.java │ │ ├── CookiesOutInterceptor.java │ │ ├── CookiesInInterceptor.java │ │ └── BadContextTokenInFaultInterceptor.java │ └── client │ │ ├── CorrespondenceEC2Client.java │ │ ├── ReporteeElementListEC2Client.java │ │ ├── IntermediaryInboundExternalEC2Client.java │ │ ├── BrokerServiceEC2StreamedClient.java │ │ ├── BrokerEC2Client.java │ │ ├── BrokerServiceEC2Client.java │ │ └── ReceiptEC2Client.java │ ├── vo │ ├── ServiceCode.java │ ├── ReceiptReference.java │ ├── UploadResponse.java │ ├── SearchCriteria.java │ ├── SubReceipt.java │ ├── UploadManifest.java │ └── SecurityCredentials.java │ ├── util │ └── DateConverter.java │ └── config │ └── EC2ClientConfig.java ├── README.md ├── .gitignore ├── LICENSE ├── formidling-gui.fxml └── pom.xml /images/UpdateAlias_keytool.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/altinn/ec-client-java-cxf/main/images/UpdateAlias_keytool.PNG -------------------------------------------------------------------------------- /images/GetCertificate_info_keytool.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/altinn/ec-client-java-cxf/main/images/GetCertificate_info_keytool.PNG -------------------------------------------------------------------------------- /images/SoapUI_altinn_example_Capture.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/altinn/ec-client-java-cxf/main/images/SoapUI_altinn_example_Capture.JPG -------------------------------------------------------------------------------- /images/Formidlingtjenesten_sekvensdiagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/altinn/ec-client-java-cxf/main/images/Formidlingtjenesten_sekvensdiagram.jpg -------------------------------------------------------------------------------- /images/Formidlingtjenesten_sekvensdiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/altinn/ec-client-java-cxf/main/images/Formidlingtjenesten_sekvensdiagram.png -------------------------------------------------------------------------------- /images/Windows_certificate_details_Capture.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/altinn/ec-client-java-cxf/main/images/Windows_certificate_details_Capture.JPG -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "local>Altinn/renovate-config" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /src/test/resources/LANGESUND_OG_MÅLØY_REGNSKAP.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/altinn/ec-client-java-cxf/main/src/test/resources/LANGESUND_OG_MÅLØY_REGNSKAP.p12 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ec-client-java-cxf 2 | Demonstrerer bruk av virksomhetssertifikater mot Altinns webservicer. 3 | 4 | [Se utviklerguiden for tekniske detaljer](../master/utviklerguide.md) 5 | -------------------------------------------------------------------------------- /src/test/resources/COMMFIDES_BAREKSTAD_OG_YTTERVÅG_REGNSKAP.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/altinn/ec-client-java-cxf/main/src/test/resources/COMMFIDES_BAREKSTAD_OG_YTTERVÅG_REGNSKAP.p12 -------------------------------------------------------------------------------- /src/test/resources/Buypass_ID-KYSTBASEN_ÅGOTNES_OG_ILSENG_REGNSKAP.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/altinn/ec-client-java-cxf/main/src/test/resources/Buypass_ID-KYSTBASEN_ÅGOTNES_OG_ILSENG_REGNSKAP.p12 -------------------------------------------------------------------------------- /src/test/resources/Buypass ID-LANGESUND OG MÅLØY REGNSKAP-serienummer2075247706312279234458841-2018-06-28.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/altinn/ec-client-java-cxf/main/src/test/resources/Buypass ID-LANGESUND OG MÅLØY REGNSKAP-serienummer2075247706312279234458841-2018-06-28.p12 -------------------------------------------------------------------------------- /src/main/resources/properties/formidling-tjeneste.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Angir hvilken formidlingstjeneste og versjon 5 | 4797 6 | 1 7 | 8 | -------------------------------------------------------------------------------- /src/test/resources/properties/formidling-tjeneste.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Angir hvilken formidlingstjeneste og versjon 5 | 4797 6 | 1 7 | 8 | -------------------------------------------------------------------------------- /src/main/resources/properties/logging-properties.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Logging nivå 5 | ERROR 6 | ERROR 7 | ERROR 8 | DEBUG 9 | 10 | -------------------------------------------------------------------------------- /src/test/resources/properties/logging-properties.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Logging nivå 5 | ERROR 6 | ERROR 7 | ERROR 8 | DEBUG 9 | 10 | -------------------------------------------------------------------------------- /src/main/java/no/asf/formidling/client/ws/cookie/CookieStore.java: -------------------------------------------------------------------------------- 1 | package no.asf.formidling.client.ws.cookie; 2 | 3 | /** 4 | * Lagrer en Cookie i trådens minne. 5 | */ 6 | public class CookieStore { 7 | 8 | private static ThreadLocal requestCookie = new ThreadLocal(); 9 | 10 | public static void setCookie(Object cookie) { 11 | requestCookie.set(cookie); 12 | } 13 | 14 | public static Object getCookie() { 15 | return requestCookie.get(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled source # 2 | ################### 3 | *.com 4 | *.class 5 | *.dll 6 | *.exe 7 | *.o 8 | *.so 9 | target/ 10 | .idea/ 11 | *.iml 12 | 13 | # Packages # 14 | ############ 15 | # it's better to unpack these files and commit the raw source 16 | # git has its own built in compression methods 17 | *.7z 18 | *.dmg 19 | *.gz 20 | *.iso 21 | *.jar 22 | *.rar 23 | *.tar 24 | *.zip 25 | *.war 26 | *.ear 27 | *.tar.gz 28 | 29 | # Logs and databases # 30 | ###################### 31 | *.log 32 | *.sql 33 | *.sqlite 34 | 35 | # OS generated files # 36 | ###################### 37 | .DS_Store 38 | .DS_Store? 39 | ._* 40 | .Spotlight-V100 41 | .Trashes 42 | ehthumbs.db 43 | Thumbs.db -------------------------------------------------------------------------------- /src/test/resources/FormTask.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mr. Altinn 6 | 7 | Dens vei 6 8 | 8347 9 | Innsia 10 | 11 | 12 | 13 | Tornes og Bjerka 14 | 15 | Bygda 16 | 8451 17 | Yttersia 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/properties/avgiver-properties.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Angir data for avgiver 5 | 810514442 6 | BAREKSTAD OG YTTERVÅG REGNSKAP 7 | lbKEX9fB 8 | COMMFIDES_BAREKSTAD_OG_YTTERVÅG_REGNSKAP.p12 9 | Authentication certificate 10 | antonio 11 | malik101 12 | 13 | -------------------------------------------------------------------------------- /src/test/resources/properties/mottaker-properties.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Angir data for mottaker 5 | 910514318 6 | KYSTBASEN ÅGOTNES OG ILSENG REGNSKAP 7 | Uh9N32hHFzKfTEcx 8 | Buypass_ID-KYSTBASEN_ÅGOTNES_OG_ILSENG_REGNSKAP.p12 9 | KYSTBASEN ÅGOTNES OG ILSENG REGNSKAP 10 | kystbasentest5 11 | test123 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/resources/properties/formidling-uri.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Altinn formidling webservice URI 5 | https://tt02.altinn.no/ServiceEngineExternal/BrokerServiceExternalEC2.svc 6 | https://tt02.altinn.no/ServiceEngineExternal/BrokerServiceExternalEC2Streamed.svc 7 | https://tt02.altinn.no/IntermediaryExternal/ReceiptExternalEC2.svc 8 | https://tt02.altinn.no/ServiceEngineExternal/CorrespondenceExternalEC2.svc 9 | https://tt02.altinn.no/ServiceEngineExternal/ReporteeElementListEC2.svc 10 | 11 | -------------------------------------------------------------------------------- /src/main/java/no/asf/formidling/client/vo/ServiceCode.java: -------------------------------------------------------------------------------- 1 | package no.asf.formidling.client.vo; 2 | 3 | /** 4 | * Holder identifikator for formidlingstjenesten. 5 | * 6 | * Immutable value object. 7 | */ 8 | public class ServiceCode { 9 | 10 | private String externalServiceCode; 11 | 12 | private int externalServiceEditionCode; 13 | 14 | /** 15 | * Construnctor. 16 | * 17 | * @param serviceCode Den unike kode for en formidlingstjeneste 18 | * @param serviceEditionCode Versjonsnummer av formidlingstjenesten. 19 | */ 20 | public ServiceCode(String serviceCode, int serviceEditionCode){ 21 | this.externalServiceCode = serviceCode; 22 | this.externalServiceEditionCode = serviceEditionCode; 23 | } 24 | 25 | public String getExternalServiceCode() { 26 | return externalServiceCode; 27 | } 28 | 29 | public int getExternalServiceEditionCode() { 30 | return externalServiceEditionCode; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/test/resources/properties/formidling-uri.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Altinn formidling webservice URI 5 | https://tt02.altinn.no/ServiceEngineExternal/BrokerServiceExternalEC2.svc 6 | https://tt02.altinn.no/ServiceEngineExternal/BrokerServiceExternalEC2Streamed.svc 7 | https://tt02.altinn.no/IntermediaryExternal/ReceiptExternalEC2.svc 8 | https://tt02.altinn.no/ServiceEngineExternal/CorrespondenceExternalEC2.svc 9 | https://tt02.altinn.no/ServiceEngineExternal/ReporteeElementListEC2.svc 10 | https://tt02.altinn.no/IntermediaryExternal/IntermediaryInboundExternalEC2.svc 11 | 12 | -------------------------------------------------------------------------------- /src/main/java/no/asf/formidling/client/vo/ReceiptReference.java: -------------------------------------------------------------------------------- 1 | package no.asf.formidling.client.vo; 2 | 3 | import no.altinn.receiptexternalec.ReferenceType; 4 | 5 | /** 6 | * Referanse brukt i Altinn kvittering. Kan brukes ved oppdatering av kvittering. 7 | * 8 | * Immutable value object. 9 | */ 10 | public class ReceiptReference { 11 | 12 | private ReferenceType referenceType; 13 | 14 | private String referenceValue; 15 | 16 | /** 17 | * Constructor. 18 | * 19 | * @param referenceType ReceiversReference, mottakers referanse hvis kvitteringen blir oppdatert av mottaker av en forsendelse 20 | * @param referenceValue Referansens verdi 21 | */ 22 | public ReceiptReference(ReferenceType referenceType, String referenceValue){ 23 | this.referenceType = referenceType; 24 | this.referenceValue = referenceValue; 25 | } 26 | 27 | public ReferenceType getReferenceType() { 28 | return referenceType; 29 | } 30 | 31 | public String getReferenceValue() { 32 | return referenceValue; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Altinn 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/main/java/no/asf/formidling/client/vo/UploadResponse.java: -------------------------------------------------------------------------------- 1 | package no.asf.formidling.client.vo; 2 | 3 | import no.altinn.brokerserviceexternalecstreamed.ReceiptExternalStreamedBE; 4 | 5 | /** 6 | * Holder filreferanse fra initialisering av broker 7 | * og kvittering fra opplasting til formidlingstjenesten. 8 | * 9 | */ 10 | public class UploadResponse { 11 | 12 | private String fileReference; 13 | 14 | private ReceiptExternalStreamedBE receiptStreamed; 15 | 16 | /** 17 | * @return filreferanse fra initialisering av serviceBroker 18 | */ 19 | public String getFileReference() { 20 | return fileReference; 21 | } 22 | 23 | public void setFileReference(String fileReference) { 24 | this.fileReference = fileReference; 25 | } 26 | 27 | /** 28 | * @return Kvittering fra opplasting til formidlingstjenesten. 29 | */ 30 | public ReceiptExternalStreamedBE getReceiptStreamed() { 31 | return receiptStreamed; 32 | } 33 | 34 | public void setReceiptStreamed(ReceiptExternalStreamedBE receiptStreamed) { 35 | this.receiptStreamed = receiptStreamed; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/no/asf/formidling/client/util/DateConverter.java: -------------------------------------------------------------------------------- 1 | package no.asf.formidling.client.util; 2 | 3 | import javax.xml.datatype.DatatypeConfigurationException; 4 | import javax.xml.datatype.DatatypeFactory; 5 | import javax.xml.datatype.XMLGregorianCalendar; 6 | import java.util.Date; 7 | import java.util.GregorianCalendar; 8 | 9 | /** 10 | * Utility for å konvertere dato til format brukt i webservice grensesnittet. 11 | */ 12 | public class DateConverter { 13 | 14 | /** 15 | * Konverter Date til XMLGregorianCalendar. 16 | * 17 | * @param inDate Dato som skal konverteres 18 | * @return XMLGregorianCalendar 19 | * @throws DatatypeConfigurationException Exception ved konvertering av dato 20 | */ 21 | static public XMLGregorianCalendar convertToXMLGregorianCalendar(Date inDate) throws DatatypeConfigurationException { 22 | if (inDate != null) { 23 | GregorianCalendar gcal = new GregorianCalendar(); 24 | gcal.setTime(inDate); 25 | XMLGregorianCalendar xgcal = DatatypeFactory.newInstance().newXMLGregorianCalendar(gcal); 26 | return xgcal; 27 | } else { 28 | return null; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/no/asf/formidling/client/ws/interceptor/HeaderInterceptor.java: -------------------------------------------------------------------------------- 1 | package no.asf.formidling.client.ws.interceptor; 2 | 3 | import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor; 4 | import org.apache.cxf.interceptor.Fault; 5 | import org.apache.cxf.message.Message; 6 | import org.apache.cxf.phase.AbstractPhaseInterceptor; 7 | import org.apache.cxf.phase.Phase; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.util.Collections; 12 | import java.util.List; 13 | import java.util.Map; 14 | 15 | /** 16 | * Interceptor for å legge til attributten Connection med verdi Keep-Alive 17 | * i header på utgående webservice melding. 18 | */ 19 | public class HeaderInterceptor extends AbstractPhaseInterceptor { 20 | 21 | private Logger log = LoggerFactory.getLogger(this.getClass()); 22 | 23 | public HeaderInterceptor() { 24 | super(Phase.PRE_PROTOCOL_ENDING); 25 | getAfter().add(SAAJOutInterceptor.SAAJOutEndingInterceptor.class.getName()); 26 | } 27 | 28 | @Override 29 | public void handleMessage(Message message) throws Fault { 30 | log.info("Adding Keep-Alive header"); 31 | Map headers = (Map) message.get(Message.PROTOCOL_HEADERS); 32 | headers.put("Connection", Collections.singletonList("Keep-Alive")); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/no/asf/formidling/client/ws/interceptor/CookiesOutInterceptor.java: -------------------------------------------------------------------------------- 1 | package no.asf.formidling.client.ws.interceptor; 2 | 3 | 4 | import no.asf.formidling.client.ws.cookie.CookieStore; 5 | import org.apache.cxf.interceptor.Fault; 6 | import org.apache.cxf.message.Message; 7 | import org.apache.cxf.phase.AbstractPhaseInterceptor; 8 | import org.apache.cxf.phase.Phase; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import java.util.Collections; 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | /** 17 | * Interceptor for å hente Cookie fra {@link CookieStore} og legge til i header i utgående webservice melding. 18 | */ 19 | public class CookiesOutInterceptor extends AbstractPhaseInterceptor { 20 | 21 | private Logger log = LoggerFactory.getLogger(this.getClass()); 22 | 23 | public CookiesOutInterceptor() { 24 | super(Phase.PRE_PROTOCOL); 25 | } 26 | 27 | @Override 28 | public void handleMessage(Message message) throws Fault { 29 | Map headers = (Map) message.get(Message.PROTOCOL_HEADERS); 30 | if (CookieStore.getCookie() != null) { 31 | log.info("CookiesOUTInterceptor -- cookie to attach to header: " + CookieStore.getCookie()); 32 | headers.put("Cookie", Collections.singletonList(CookieStore.getCookie())); 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/no/asf/formidling/client/ws/interceptor/CookiesInInterceptor.java: -------------------------------------------------------------------------------- 1 | package no.asf.formidling.client.ws.interceptor; 2 | 3 | import no.asf.formidling.client.ws.cookie.CookieStore; 4 | import org.apache.cxf.interceptor.Fault; 5 | import org.apache.cxf.message.Message; 6 | import org.apache.cxf.phase.AbstractPhaseInterceptor; 7 | import org.apache.cxf.phase.Phase; 8 | import org.apache.cxf.transport.http.Cookie; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import java.util.List; 13 | import java.util.Map; 14 | 15 | /** 16 | * Interceptor for å plukke opp Cookie fra header i innkommende webservice melding. 17 | * Den vil da finnes som en attributt Set-Cookie. Hvis funnet så lagres den i {@link CookieStore}. 18 | */ 19 | public class CookiesInInterceptor extends AbstractPhaseInterceptor { 20 | 21 | private Logger log = LoggerFactory.getLogger(this.getClass()); 22 | 23 | public CookiesInInterceptor() { 24 | super(Phase.PRE_PROTOCOL); 25 | } 26 | 27 | @Override 28 | public void handleMessage(Message message) throws Fault { 29 | Map headers = (Map) message.get(Message.PROTOCOL_HEADERS); 30 | List cookies= headers.get("Set-Cookie"); 31 | if(cookies != null) { 32 | log.info("CookiesInInterceptor -- cookie to be stored in cookiestore: " + cookies.get(0)); 33 | CookieStore.setCookie(cookies.get(0)); 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/no/asf/formidling/client/vo/SearchCriteria.java: -------------------------------------------------------------------------------- 1 | package no.asf.formidling.client.vo; 2 | 3 | import no.altinn.brokerserviceexternalec.BrokerServiceAvailableFileStatus; 4 | 5 | import java.util.Date; 6 | 7 | /** 8 | * Holder søkekriterier for å finne tilgjengelige formidlinger for en mottaker. 9 | * 10 | * Immutable value object. 11 | */ 12 | public class SearchCriteria { 13 | 14 | private BrokerServiceAvailableFileStatus availableFileStatus; 15 | 16 | private Date minSentDate; 17 | 18 | private Date maxSentDate; 19 | 20 | /** 21 | * Constructor. 22 | * 23 | * @param availableFileStatus Status for formidlingstjenesten. Mulige verdier er: 24 | * - Uploaded, betyr at formidlingstjenesten er lastet opp av avsender og tilgjengelig for nedlasting. 25 | * - Downloaded, betyr at formidlingstjenesten allerede er lastet ned fra Altinn, men fremdeles tilgjengelig for nedlasting. 26 | * @param minSentDate Angir dato for å begrense resultatsett av formidlingstjenester sent inn etter angitt dato 27 | * @param maxSentDate Angir dato for å begrense resultatsett av formidlingstjenester sent før angitt dato 28 | */ 29 | public SearchCriteria(BrokerServiceAvailableFileStatus availableFileStatus, Date minSentDate, Date maxSentDate){ 30 | this.availableFileStatus = availableFileStatus; 31 | this.minSentDate = minSentDate; 32 | this.maxSentDate = maxSentDate; 33 | } 34 | 35 | public BrokerServiceAvailableFileStatus getAvailableFileStatus() { 36 | return availableFileStatus; 37 | } 38 | 39 | public Date getMinSentDate() { 40 | return minSentDate; 41 | } 42 | 43 | public Date getMaxSentDate() { 44 | return maxSentDate; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/no/asf/formidling/client/vo/SubReceipt.java: -------------------------------------------------------------------------------- 1 | package no.asf.formidling.client.vo; 2 | 3 | import no.altinn.receiptexternalec.ReceiptStatusEnum; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Brukes ved oppdatering av underkvitteringer (subreceipt). 9 | * 10 | * Immutable value object. 11 | */ 12 | public class SubReceipt { 13 | 14 | private String archiveReference; 15 | 16 | private Integer receiptId; 17 | 18 | private ReceiptStatusEnum receiptStatus; 19 | 20 | private String receiptText; 21 | 22 | private List references; 23 | 24 | private List subReceipts; 25 | 26 | /** 27 | * Constructor. 28 | * 29 | * @param archiveReference Hvis det finnes flere kvitteringer med samme arkivreferanse så vil den nyeste bli valgt 30 | * @param receiptId Unik identifikator for kvittering 31 | * @param receiptStatus Status for forsendelse som kvitteringen gjelder: OK, UnExpectedError, ValidationFailed, Rejected 32 | * @param receiptText Oppdateringstekst for kvittering 33 | * @param references Liste med referanser man ønsker legge til, bør begrenses til ReceiversReference 34 | * @param subReceipts Liste med barnekvitteringer som også ønskes oppdatert i tillegg til hovedkvitteringen. 35 | * Barnekvitteringer MÅ identifiseres med ReceiptId. Dette kan ikke benyttes til å lage nye barnekvitteringer. 36 | */ 37 | public SubReceipt(String archiveReference, Integer receiptId, ReceiptStatusEnum receiptStatus, String receiptText, List references, List subReceipts){ 38 | this.archiveReference = archiveReference; 39 | this.receiptId = receiptId; 40 | this.receiptStatus = receiptStatus; 41 | this.receiptText = receiptText; 42 | this.references = references; 43 | this.subReceipts = subReceipts; 44 | } 45 | 46 | public String getArchiveReference() { 47 | return archiveReference; 48 | } 49 | 50 | public Integer getReceiptId() { 51 | return receiptId; 52 | } 53 | 54 | public ReceiptStatusEnum getReceiptStatus() { 55 | return receiptStatus; 56 | } 57 | 58 | public String getReceiptText() { 59 | return receiptText; 60 | } 61 | 62 | public List getReferences() { 63 | return references; 64 | } 65 | 66 | public List getSubReceipts() { 67 | return subReceipts; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/no/asf/formidling/client/vo/UploadManifest.java: -------------------------------------------------------------------------------- 1 | package no.asf.formidling.client.vo; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * Holder data om filer som skal til formidlingstjenesten. 10 | * 11 | * Immutable value object. 12 | */ 13 | public class UploadManifest { 14 | 15 | private List recipientList; 16 | 17 | private List fileList; 18 | 19 | private String zipFileName; 20 | 21 | private String sendersReference; 22 | 23 | private Map properties; 24 | 25 | /** 26 | * Constructor. 27 | * 28 | * @param sendersReference Referanse som formidlingstjenesten skal knyttes til. Bør være unik. Feltet er påkrevd. 29 | * @param fileList Liste av objekter av typen File. Ment for å kunne utveksle informasjon om 30 | * innholdet i formidlingstjenesten etter avtale mellom avsender og mottaker. 31 | * Innhold valideres eller endres ikke av Altinn. Feltet er ikke påkrevd. 32 | * @param recipientList Liste av organisasjonsnummer eller fødselsnummer for mottakere av av formidlingstjenesten. 33 | * @param zipFileName Filnavn for komprimert "payload" fil. 34 | * @param properties Liste av objekter av typen Property. Ment for å kunne utveksle ytterlige egenskaper 35 | * om formidlingstjenesten med nøkkel og verdi etter avtale mellom avsender og mottaker. 36 | * Innhold valideres eller endres ikke av Altinn. Feltet er ikke påkrevd. 37 | */ 38 | public UploadManifest(String sendersReference, List fileList, List recipientList, String zipFileName, Map properties) { 39 | this.sendersReference = sendersReference; 40 | this.fileList = fileList; 41 | this.recipientList = recipientList; 42 | this.zipFileName = zipFileName; 43 | this.properties = properties; 44 | } 45 | 46 | 47 | public List getRecipientList() { 48 | return recipientList; 49 | } 50 | 51 | public List getFileList() { 52 | return fileList; 53 | } 54 | 55 | public String getZipFileName() { 56 | return zipFileName; 57 | } 58 | 59 | public String getSendersReference() { 60 | return sendersReference; 61 | } 62 | 63 | public Map getProperties() { 64 | return properties; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/no/asf/formidling/client/vo/SecurityCredentials.java: -------------------------------------------------------------------------------- 1 | package no.asf.formidling.client.vo; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import java.util.Properties; 6 | 7 | /** 8 | * Holder sikkerhetsinformasjon for tilgang til formidlingstjenesten 9 | * for en virksomhetsbruker. 10 | * 11 | * Immutable value object. 12 | */ 13 | @Component 14 | public class SecurityCredentials { 15 | 16 | private Properties keyStoreProperties; 17 | 18 | private String virksomhetsbruker; 19 | 20 | private String virksomhetsbrukerPassord; 21 | 22 | private String enhet; 23 | 24 | /** 25 | * Constructor. 26 | * 27 | * @param virksomhetsbruker Brukernavn for virksomhetsbruker 28 | * @param virksomhetsbrukerPassord Passord for virksomhetsbruker 29 | * @param enhet Virksomhetens organisasjonsnummer 30 | * @param securityFile Virksomhetens sertifikat (formast PKCS12) 31 | * @param securityPassword Passord tilhørende sertifikat 32 | * @param securityAlias Alias tilhørende sertifikat (aka. friendly name) 33 | */ 34 | public SecurityCredentials(String virksomhetsbruker, 35 | String virksomhetsbrukerPassord, 36 | String enhet, 37 | String securityFile, 38 | String securityPassword, 39 | String securityAlias){ 40 | this.virksomhetsbruker = virksomhetsbruker; 41 | this.virksomhetsbrukerPassord = virksomhetsbrukerPassord; 42 | this.enhet = enhet; 43 | keyStoreProperties = new Properties(); 44 | keyStoreProperties.setProperty("org.apache.ws.security.crypto.provider","org.apache.ws.security.components.crypto.Merlin"); 45 | keyStoreProperties.setProperty("org.apache.ws.security.crypto.merlin.keystore.file", securityFile); 46 | keyStoreProperties.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", securityPassword); 47 | keyStoreProperties.setProperty("org.apache.ws.security.crypto.merlin.keystore.type","pkcs12"); 48 | keyStoreProperties.setProperty("org.apache.ws.security.crypto.merlin.keystore.private.password", securityPassword); 49 | keyStoreProperties.setProperty("org.apache.ws.security.crypto.merlin.keystore.alias", securityAlias); 50 | } 51 | 52 | public Properties getKeyStoreProperties(){ 53 | return keyStoreProperties; 54 | } 55 | 56 | public String getVirksomhetsbruker() { 57 | return virksomhetsbruker; 58 | } 59 | 60 | public String getVirksomhetsbrukerPassord() { 61 | return virksomhetsbrukerPassord; 62 | } 63 | 64 | public String getEnhet() { 65 | return enhet; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/no/asf/formidling/client/ws/client/CorrespondenceEC2Client.java: -------------------------------------------------------------------------------- 1 | package no.asf.formidling.client.ws.client; 2 | 3 | import no.altinn.correspondenceexternalec.*; 4 | import no.asf.formidling.client.config.EC2ClientConfig; 5 | import no.asf.formidling.client.vo.SecurityCredentials; 6 | import org.apache.cxf.endpoint.Client; 7 | import org.apache.cxf.frontend.ClientProxy; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import javax.xml.ws.BindingProvider; 12 | import java.util.Properties; 13 | 14 | public class CorrespondenceEC2Client { 15 | 16 | private Logger log = LoggerFactory.getLogger(this.getClass()); 17 | 18 | private ObjectFactory objectFactory; 19 | 20 | private ICorrespondenceExternalEC2 correspondenceExternalEC2; 21 | 22 | private SecurityCredentials credentials; 23 | 24 | /** 25 | * Construnctor. 26 | * 27 | * @param credentials Sikkerhetsinformasjon for tilgang til formidlingstjenesten for en virksomhetsbruker. 28 | */ 29 | public CorrespondenceEC2Client(SecurityCredentials credentials) { 30 | this.credentials = credentials; 31 | this.objectFactory = new ObjectFactory(); 32 | this.correspondenceExternalEC2 = getCorrespondenceClient(credentials.getKeyStoreProperties()); 33 | } 34 | 35 | protected CorrespondenceForEndUserSystemV2 getCorrespondenceForEndUserSystemsEC(int reporteeElementID, int languageID) throws ICorrespondenceExternalEC2GetCorrespondenceForEndUserSystemsECAltinnFaultFaultFaultMessage { 36 | 37 | return correspondenceExternalEC2.getCorrespondenceForEndUserSystemsEC(credentials.getVirksomhetsbruker(), credentials.getVirksomhetsbrukerPassord(), reporteeElementID, languageID); 38 | 39 | } 40 | 41 | private ICorrespondenceExternalEC2 getCorrespondenceClient(Properties signatureProperties) { 42 | CorrespondenceExternalEC2SF service = new CorrespondenceExternalEC2SF(); 43 | ICorrespondenceExternalEC2 port = service.getCustomBindingICorrespondenceExternalEC2(); 44 | BindingProvider bindingProvider = (BindingProvider) port; 45 | bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, EC2ClientConfig.CORRESPONDENCE_SERVICE_EXTERNAL_EC2); 46 | Client client = ClientProxy.getClient(port); 47 | client.getRequestContext().put("security.must-understand", true); 48 | client.getRequestContext().put("org.apache.cxf.message.Message.MAINTAIN_SESSION", true); 49 | client.getRequestContext().put("javax.xml.ws.session.maintain", true); 50 | client.getRequestContext().put("security.cache.issued.token.in.endpoint", true); //default: true 51 | client.getRequestContext().put("security.issue.after.failed.renew", true); //This must be set to true (default: true) 52 | client.getRequestContext().put("security.signature.properties", signatureProperties); 53 | return port; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/no/asf/formidling/client/ws/interceptor/BadContextTokenInFaultInterceptor.java: -------------------------------------------------------------------------------- 1 | package no.asf.formidling.client.ws.interceptor; 2 | 3 | import no.asf.formidling.client.ws.cookie.CookieStore; 4 | import org.apache.cxf.binding.soap.SoapFault; 5 | import org.apache.cxf.binding.soap.interceptor.Soap12FaultInInterceptor; 6 | import org.apache.cxf.interceptor.Fault; 7 | import org.apache.cxf.message.Message; 8 | import org.apache.cxf.phase.AbstractPhaseInterceptor; 9 | import org.apache.cxf.phase.Phase; 10 | import org.apache.cxf.ws.security.SecurityConstants; 11 | import org.apache.cxf.ws.security.tokenstore.TokenStoreUtils; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | 15 | import javax.xml.namespace.QName; 16 | import java.util.List; 17 | 18 | /** 19 | * Interceptor for å håndtere feil med context token. 20 | */ 21 | public class BadContextTokenInFaultInterceptor extends AbstractPhaseInterceptor { 22 | 23 | private Logger log = LoggerFactory.getLogger(this.getClass()); 24 | 25 | private static final String ERROR_CODE_BAD_CONTEXT_TOKEN = "BadContextToken"; 26 | 27 | public BadContextTokenInFaultInterceptor() { 28 | super(Phase.UNMARSHAL); 29 | getAfter().add(Soap12FaultInInterceptor.class.getName()); 30 | } 31 | 32 | @Override 33 | public void handleMessage(Message message) throws Fault { 34 | Exception exception = message.getContent(Exception.class); 35 | if (exception instanceof SoapFault) { 36 | log.error("Server Gods not happy, sent you a soapFault.. Trying to recover.."); 37 | SoapFault soapFault = (SoapFault) exception; 38 | List subCodes = soapFault.getSubCodes(); 39 | for (QName subCode : subCodes) { 40 | log.error("Found subCode: " + subCode.getLocalPart()); 41 | if (subCode.getLocalPart().equalsIgnoreCase(ERROR_CODE_BAD_CONTEXT_TOKEN)) { 42 | String tokenId = (String)message.getContextualProperty(SecurityConstants.TOKEN_ID); 43 | removeTokenFromMessageAndTokenStore(message, tokenId); 44 | CookieStore.setCookie(null); 45 | soapFault.setMessage("Token " + tokenId + " is removed from tokenstore, a new one will be requested on your next call. Message from server: " + soapFault.getMessage()); 46 | message.setContent(Exception.class, soapFault); 47 | } 48 | } 49 | } 50 | } 51 | 52 | private void removeTokenFromMessageAndTokenStore(Message message, String tokenId) { 53 | message.getExchange().getEndpoint().remove(SecurityConstants.TOKEN); 54 | message.getExchange().getEndpoint().remove(SecurityConstants.TOKEN_ID); 55 | message.getExchange().remove(SecurityConstants.TOKEN_ID); 56 | message.getExchange().remove(SecurityConstants.TOKEN); 57 | TokenStoreUtils.getTokenStore(message).remove(tokenId); 58 | log.error("Removed token " + tokenId + " from message and tokenStore"); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/no/asf/formidling/client/ws/client/IntermediaryInboundTest.java: -------------------------------------------------------------------------------- 1 | package no.asf.formidling.client.ws.client; 2 | 3 | import no.altinn.intermediaryinboundec.ReceiptExternalBE; 4 | import no.asf.formidling.client.config.EC2ClientConfig; 5 | import no.asf.formidling.client.vo.SecurityCredentials; 6 | import org.apache.commons.io.FileUtils; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.core.io.ClassPathResource; 13 | import org.springframework.test.context.ContextConfiguration; 14 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 15 | 16 | import java.io.IOException; 17 | import java.util.Properties; 18 | import java.util.UUID; 19 | 20 | import static org.hamcrest.core.Is.is; 21 | import static org.junit.Assert.assertThat; 22 | import static org.junit.Assert.fail; 23 | 24 | @ContextConfiguration(classes = {EC2ClientConfig.class}) 25 | @RunWith(SpringJUnit4ClassRunner.class) 26 | public class IntermediaryInboundTest { 27 | 28 | private Logger log = LoggerFactory.getLogger(this.getClass()); 29 | 30 | private SecurityCredentials avgiverCredentials; 31 | 32 | private IntermediaryInboundExternalEC2Client inboundExternalEC2Client; 33 | 34 | @Before 35 | public void setup() { 36 | Properties properties = new Properties(); 37 | try { 38 | properties.loadFromXML(new ClassPathResource("properties/avgiver-properties.xml").getInputStream()); 39 | } catch (IOException e) { 40 | fail("Unable to load properties"); 41 | } 42 | log.info("Getting receipt for\n" + 43 | "Avgiver = " + properties.getProperty("avgiver.entityusername")); 44 | 45 | avgiverCredentials = new SecurityCredentials(properties.getProperty("avgiver.virksomhetsbruker"), 46 | properties.getProperty("avgiver.virksomhetsbrukerpassord"), 47 | properties.getProperty("avgiver.entity"), 48 | properties.getProperty("avgiver.certificate"), 49 | properties.getProperty("avgiver.entitypassword"), 50 | properties.getProperty("avgiver.alias")); 51 | 52 | inboundExternalEC2Client = new IntermediaryInboundExternalEC2Client(avgiverCredentials); 53 | } 54 | 55 | @Test 56 | public void sendFormTaskTest() throws Exception{ 57 | ClassPathResource classPathResource = new ClassPathResource("FormTask.xml"); 58 | String formData = FileUtils.readFileToString(classPathResource.getFile(), "utf-8"); 59 | String externalShipmentReference = UUID.randomUUID().toString(); 60 | String endUserSystemReference = UUID.randomUUID().toString(); 61 | String reportee = "810514442"; 62 | String serviceCode = "3928"; 63 | int serviceEdition = 1; 64 | String dataFormatId = "3881"; 65 | int dataFormatVersion = 34642; 66 | ReceiptExternalBE receiptExternalBE = inboundExternalEC2Client.sendFormTaskShipment(reportee, externalShipmentReference, serviceCode, 67 | serviceEdition, dataFormatId, dataFormatVersion, endUserSystemReference, formData); 68 | assertThat(receiptExternalBE.getReceiptStatusCode().value(), is("OK")); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/no/asf/formidling/client/ws/client/ReporteeElementListEC2Client.java: -------------------------------------------------------------------------------- 1 | package no.asf.formidling.client.ws.client; 2 | 3 | import no.altinn.reporteeelementlistec.*; 4 | import no.asf.formidling.client.config.EC2ClientConfig; 5 | import no.asf.formidling.client.util.DateConverter; 6 | import no.asf.formidling.client.vo.SecurityCredentials; 7 | import org.apache.cxf.endpoint.Client; 8 | import org.apache.cxf.frontend.ClientProxy; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import javax.xml.datatype.DatatypeConfigurationException; 13 | import javax.xml.datatype.XMLGregorianCalendar; 14 | import javax.xml.ws.BindingProvider; 15 | import java.text.ParseException; 16 | import java.text.SimpleDateFormat; 17 | import java.util.Date; 18 | import java.util.Properties; 19 | 20 | public class ReporteeElementListEC2Client { 21 | 22 | private Logger log = LoggerFactory.getLogger(this.getClass()); 23 | 24 | private ObjectFactory objectFactory; 25 | 26 | private IReporteeElementListEC2 reporteeElementListEC2; 27 | 28 | private SecurityCredentials credentials; 29 | 30 | public ReporteeElementListEC2Client(SecurityCredentials credentials) { 31 | this.credentials = credentials; 32 | this.objectFactory = new ObjectFactory(); 33 | this.reporteeElementListEC2 = getReporteeElementListEC2(credentials.getKeyStoreProperties()); 34 | } 35 | 36 | protected ReporteeElementBEV2Lis getReporteeElementListEC2(String reportee, XMLGregorianCalendar fromDate, XMLGregorianCalendar toDate, int languageID) throws ParseException, DatatypeConfigurationException, IReporteeElementListEC2GetReporteeElementListECAltinnFaultFaultFaultMessage { 37 | 38 | return reporteeElementListEC2.getReporteeElementListEC(credentials.getVirksomhetsbruker(), credentials.getVirksomhetsbrukerPassord(), getExternalSearchBEV2(reportee, fromDate, toDate), languageID); 39 | } 40 | 41 | private ExternalSearchBEV2 getExternalSearchBEV2(String reportee, XMLGregorianCalendar fromDate, XMLGregorianCalendar toDate) throws ParseException, DatatypeConfigurationException { 42 | ExternalSearchBEV2 externalSearchBEV2 = objectFactory.createExternalSearchBEV2(); 43 | externalSearchBEV2.setFromDate(fromDate); 44 | externalSearchBEV2.setToDate(toDate); 45 | externalSearchBEV2.setReportee(reportee); 46 | externalSearchBEV2.setSentAndArchived(false); 47 | return externalSearchBEV2; 48 | } 49 | 50 | private IReporteeElementListEC2 getReporteeElementListEC2(Properties signatureProperties) { 51 | ReporteeElementListEC2SF service = new ReporteeElementListEC2SF(); 52 | IReporteeElementListEC2 port = service.getCustomBindingIReporteeElementListEC2(); 53 | BindingProvider bindingProvider = (BindingProvider) port; 54 | bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, EC2ClientConfig.REPORTEE_ELEMENT_LIST_EC2); 55 | Client client = ClientProxy.getClient(port); 56 | client.getRequestContext().put("security.must-understand", true); 57 | client.getRequestContext().put("org.apache.cxf.message.Message.MAINTAIN_SESSION", true); 58 | client.getRequestContext().put("javax.xml.ws.session.maintain", true); 59 | client.getRequestContext().put("security.cache.issued.token.in.endpoint", true); //default: true 60 | client.getRequestContext().put("security.issue.after.failed.renew", true); //This must be set to true (default: true) 61 | client.getRequestContext().put("security.signature.properties", signatureProperties); 62 | return port; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /formidling-gui.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |