work in progres

This commit is contained in:
Daniel Schick 2015-04-23 06:02:43 +00:00
parent 5f56a6c4bf
commit ff9bbf334a
48 changed files with 1714 additions and 262 deletions

33
REDIRECT.txt Normal file
View File

@ -0,0 +1,33 @@
Der einzige von außen erreichbare Server ist der Wetris Server (Domain u.a. www.schiffsmelder.de).
Um die Konfig möglichst nicht zu ändern, habe ich eine Umleitung eingerichtet.
Zunächst mit HTTP redirect, was aber den Nachteil hat, dass die neu vergebene URL nach aussen sichtbar wird.
Daher habe ich am 6.4.15 das Application Routing Redirect (ARR) auf dem Server installiert.
Damit kann man ein sog. URL rewrite machen, so dass der Zugriff auf das Unterverzeichnis
http://www.schiffsmelder.de/nswservice/ direkt auf die URL http://smnsw01.bsmd.local/
gemappt wird, und zwar ohne dass der Anwender von aussen das sieht.
Dazu wählt man das Unterverzeichnis in den IIS Einstellungen und klickt "URL Rewrite".
Rechtsklick und dann im unteren Bereich "Eingehende und ausgehende Regeln" Reverseproxy wählen.
Das klappt nur wenn man das ARR vorher installiert hat!
Dann muss man lediglich oben den Server angeben und alles wird gut.
URL Rewrite KnowHow:
Im Proxy und backend web.config müssen folgende Einträge stehen, sonst tut es nicht:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Global rewrite rules are used to define server-wide URL rewriting logic. These rules are defined within applicationHost.config file and they cannot be overridden or disabled on any lower configuration levels, such as site or virtual directory. Global rules always operate on the absolute URL path (that is, requested URI without the server name). For example if a request was made to http://localhost/directory1/directory2/index.html, then the URL rewrite module will pass “directory1/directory2/index.html” as an input to a global rule.
Distributed rewrite rules are used to define URL rewriting logic specific to a particular configuration scope. Distributed rules can be defined on any configuration level (except file) by using web.config files. Local rules always operate on URLs relative to the location of Web.config file where they are defined. For example if a request was made to http://localhost/directory1/directory2/index.html and a rewrite rule was defined in Web.config file located in directory1, then the URL rewrite module will pass “directory2/index.html” as an input to that rule.
Global rule set is always evaluated first, and after that distributed rule set will be evaluated by using a URL string produced by global rule set.
http://www.iis.net/learn/extensions/url-rewrite-module/using-global-and-distributed-rewrite-rules

Binary file not shown.

View File

@ -0,0 +1,7 @@
GO
ALTER TABLE [dbo].[MessageCore]
ADD [HerbergFormGuid] UNIQUEIDENTIFIER NULL,
[HerbergFormTemplateGuid] UNIQUEIDENTIFIER NULL;
GO

View File

@ -29,7 +29,7 @@
<applicationSettings> <applicationSettings>
<SendNSWMessageService.Properties.Settings> <SendNSWMessageService.Properties.Settings>
<setting name="ConnectionString" serializeAs="String"> <setting name="ConnectionString" serializeAs="String">
<value>replace me!</value> <value>Data Source=(localdb)\Projects;Initial Catalog=nsw;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False</value>
</setting> </setting>
</SendNSWMessageService.Properties.Settings> </SendNSWMessageService.Properties.Settings>
</applicationSettings> </applicationSettings>

View File

@ -48,10 +48,10 @@ namespace SendNSWMessageService
public void Init(string[] args) public void Init(string[] args)
{ {
this._timer = new Timer(); this._timer = new Timer();
this._timer.Interval = 5000; // 5 sec this._timer.Interval = 60000; // 1 min
this._timer.Elapsed += _timer_Elapsed; this._timer.Elapsed += _timer_Elapsed;
this._timer.Enabled = true; this._timer.Enabled = true;
_timer_Elapsed(null, null);
} }
void _timer_Elapsed(object sender, ElapsedEventArgs e) void _timer_Elapsed(object sender, ElapsedEventArgs e)
@ -67,21 +67,21 @@ namespace SendNSWMessageService
// Datenbank auf zu sendende Objekte überprüfen und laden // Datenbank auf zu sendende Objekte überprüfen und laden
List<Message> messagesToSendList = DBManager.Instance.GetToSendMessageList(); List<DatabaseEntity> messagesToSendList = DBManager.Instance.GetToSendMessageList();
foreach (Message message in messagesToSendList) foreach (DatabaseEntity entity in messagesToSendList)
{ {
try try
{ {
_log.InfoFormat("Sending CORE message for {0} application to {1}", _log.InfoFormat("Sending CORE message for {0} application to {1}",
message.MessageCore.IsTransit ? "TRANSIT" : "VISIT", message.MessageCore.InitialHIS.ToString()); entity.MessageCore.IsTransit ? "TRANSIT" : "VISIT", entity.MessageCore.InitialHIS.ToString());
bool sendSucceeded = false; bool sendSucceeded = false;
// switch über passendes HIS / Schnittstelle // switch über passendes HIS / Schnittstelle
switch (message.MessageCore.InitialHIS) switch (entity.MessageCore.InitialHIS)
{ {
case Message.NSWProvider.DBH: case Message.NSWProvider.DBH:
sendSucceeded = bsmd.dbh.Request.SendMessage(message); sendSucceeded = bsmd.dbh.Request.SendMessage(entity);
break; break;
case Message.NSWProvider.DAKOSY: case Message.NSWProvider.DAKOSY:
_log.Warn("Cannot send via DAKOSY yet"); _log.Warn("Cannot send via DAKOSY yet");
@ -91,20 +91,20 @@ namespace SendNSWMessageService
_log.Warn("Cannot send via Daten und Dienste HRO yet"); _log.Warn("Cannot send via Daten und Dienste HRO yet");
break; break;
default: default:
_log.WarnFormat("Initial HIS not specified for message {0}", message.Id); _log.WarnFormat("Initial HIS not specified for message {0}", entity.Id);
break; break;
} }
if (sendSucceeded) if (sendSucceeded)
{ {
message.InternalStatus = Message.BSMDStatus.SENT; entity.InternalStatus = Message.BSMDStatus.SENT;
DBManager.Instance.Save(message); DBManager.Instance.Save(entity);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
_log.ErrorFormat("SENDING message {0}: {1}", message.ToString(), ex.Message); _log.ErrorFormat("SENDING message {0}: {1}", entity.Id.ToString(), ex.Message);
} }
} }

View File

@ -0,0 +1,35 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34209
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace SendNSWMessageService.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("replace me!")]
public string ConnectionString {
get {
return ((string)(this["ConnectionString"]));
}
}
}
}

View File

@ -0,0 +1,9 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="SendNSWMessageService.Properties" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="ConnectionString" Type="System.String" Scope="Application">
<Value Profile="(Default)">replace me!</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@ -0,0 +1,34 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bsmd.EMailReceiveService", "bsmd.EMailReceiveService\bsmd.EMailReceiveService.csproj", "{6D46F847-24F2-4883-8B0E-21386FFD0C96}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bsmd.database", "bsmd.database\bsmd.database.csproj", "{19945AF2-379B-46A5-B27A-303B5EC1D557}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bsmd.dbh", "bsmd.dbh\bsmd.dbh.csproj", "{DF625FF0-2265-4686-9CB6-2A8511CB3B9D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6D46F847-24F2-4883-8B0E-21386FFD0C96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6D46F847-24F2-4883-8B0E-21386FFD0C96}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6D46F847-24F2-4883-8B0E-21386FFD0C96}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6D46F847-24F2-4883-8B0E-21386FFD0C96}.Release|Any CPU.Build.0 = Release|Any CPU
{19945AF2-379B-46A5-B27A-303B5EC1D557}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19945AF2-379B-46A5-B27A-303B5EC1D557}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19945AF2-379B-46A5-B27A-303B5EC1D557}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19945AF2-379B-46A5-B27A-303B5EC1D557}.Release|Any CPU.Build.0 = Release|Any CPU
{DF625FF0-2265-4686-9CB6-2A8511CB3B9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DF625FF0-2265-4686-9CB6-2A8511CB3B9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DF625FF0-2265-4686-9CB6-2A8511CB3B9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DF625FF0-2265-4686-9CB6-2A8511CB3B9D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="bsmd.EMailReceiveService.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<userSettings>
<bsmd.EMailReceiveService.Properties.Settings>
<setting name="ConnectionString" serializeAs="String">
<value>replace me!</value>
</setting>
<setting name="User" serializeAs="String">
<value>replace me!</value>
</setting>
<setting name="Host" serializeAs="String">
<value>replace me!</value>
</setting>
<setting name="Password" serializeAs="String">
<value>replace me!</value>
</setting>
<setting name="Port" serializeAs="String">
<value>995</value>
</setting>
</bsmd.EMailReceiveService.Properties.Settings>
</userSettings>
</configuration>

View File

@ -0,0 +1,37 @@
namespace bsmd.EMailReceiveService
{
partial class EmailReceiveService
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.ServiceName = "Service1";
}
#endregion
}
}

View File

@ -0,0 +1,151 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.IO;
using System.ServiceProcess;
using System.Text;
using System.Timers;
using System.Threading.Tasks;
using OpenPop;
using log4net;
using bsmd.database;
namespace bsmd.EMailReceiveService
{
/// <summary>
/// Simpler Windows-Service zum Abruf von NSW Antworten via E-mail. Ich verwende OpenPop.NET Library (via NuGet)
/// http://hpop.sourceforge.net/
///
/// </summary>
public partial class EmailReceiveService : ServiceBase
{
private Timer _timer;
private object _timerlock = new object();
private bool processRunning = false;
private ILog _log = LogManager.GetLogger(typeof(EmailReceiveService));
public EmailReceiveService()
{
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
InitializeComponent();
}
protected override void OnStart(string[] args)
{
this.EventLog.Source = this.ServiceName;
this.EventLog.Log = "Application";
this.EventLog.BeginInit();
if (!EventLog.SourceExists(this.EventLog.Source, this.EventLog.Log))
EventLog.CreateEventSource(this.EventLog.Source, this.EventLog.Log);
this.EventLog.EndInit();
this.Init(args);
this.EventLog.WriteEntry("NSW Send Service started.", EventLogEntryType.Information);
}
protected override void OnStop()
{
}
public void Init(string[] args)
{
this._timer = new Timer();
this._timer.Interval = 600000; // 10 Min, TODO: Settings
this._timer.Elapsed += _timer_Elapsed;
this._timer.Enabled = true;
if (Debugger.IsAttached)
this._timer_Elapsed(null, null);
}
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
lock (this._timerlock)
{
if (this.processRunning) return;
else this.processRunning = true;
}
if (DBManager.Instance.Connect(Properties.Settings.Default.ConnectionString))
{
try
{
// dbh E-Mail aus Postfach abrufen
using (OpenPop.Pop3.Pop3Client client = new OpenPop.Pop3.Pop3Client())
{
client.Connect(Properties.Settings.Default.Host, Properties.Settings.Default.Port, true);
client.Authenticate(Properties.Settings.Default.User, Properties.Settings.Default.Password);
int messageNum = client.GetMessageCount();
_log.DebugFormat("Mail Server has {0} messages", messageNum);
if (messageNum > 0)
{
// We want to download all messages
List<OpenPop.Mime.Message> allMessages = new List<OpenPop.Mime.Message>(messageNum);
// Messages are numbered in the interval: [1, messageCount]
// Ergo: message numbers are 1-based.
// Most servers give the latest message the highest number
for (int i = 1; i <= messageNum; i++)
{
allMessages.Add(client.GetMessage(i));
}
for (int i = 0; i < allMessages.Count; i++)
{
// XML Anhang extrahieren und in einen string schreiben
OpenPop.Mime.Message message = allMessages[i];
List<OpenPop.Mime.MessagePart> messageParts = message.FindAllAttachments();
for (int partIndex = 0; partIndex < messageParts.Count; partIndex++)
{
OpenPop.Mime.MessagePart part = messageParts[partIndex];
_log.DebugFormat("{0} Encoding: {1}", partIndex, part.ContentTransferEncoding);
switch (part.ContentTransferEncoding)
{
case OpenPop.Mime.Header.ContentTransferEncoding.Base64:
// decode base64 body
break;
default:
break;
}
}
// E-Mail entfernen
// client.DeleteMessage(i+1);
}
}
}
}
catch (Exception ex)
{
_log.ErrorFormat("Exception occurred: {0}", ex.ToString());
}
}
else
{
this.EventLog.WriteEntry("FormService stopped: DB connection failed", EventLogEntryType.Error);
this.Stop();
}
lock (this._timerlock)
{
this.processRunning = false;
}
}
}
}

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
namespace bsmd.EMailReceiveService
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new EmailReceiveService()
};
if (Debugger.IsAttached)
{
((EmailReceiveService)ServicesToRun[0]).Init(null);
while (true) ;
}
else
{
ServiceBase.Run(ServicesToRun);
}
}
}
}

View File

@ -0,0 +1,18 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("bsmd.EMailReceiveService")]
[assembly: AssemblyDescription("E-Mail checker for NSW response messages sent by mail")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("03d0b447-a06c-46ad-b888-94501a6ea618")]

View File

@ -0,0 +1,86 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34209
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace bsmd.EMailReceiveService.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("replace me!")]
public string ConnectionString {
get {
return ((string)(this["ConnectionString"]));
}
set {
this["ConnectionString"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("replace me!")]
public string User {
get {
return ((string)(this["User"]));
}
set {
this["User"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("replace me!")]
public string Host {
get {
return ((string)(this["Host"]));
}
set {
this["Host"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("replace me!")]
public string Password {
get {
return ((string)(this["Password"]));
}
set {
this["Password"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("995")]
public int Port {
get {
return ((int)(this["Port"]));
}
set {
this["Port"] = value;
}
}
}
}

View File

@ -0,0 +1,21 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="bsmd.EMailReceiveService.Properties" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="ConnectionString" Type="System.String" Scope="User">
<Value Profile="(Default)">replace me!</Value>
</Setting>
<Setting Name="User" Type="System.String" Scope="User">
<Value Profile="(Default)">replace me!</Value>
</Setting>
<Setting Name="Host" Type="System.String" Scope="User">
<Value Profile="(Default)">replace me!</Value>
</Setting>
<Setting Name="Password" Type="System.String" Scope="User">
<Value Profile="(Default)">replace me!</Value>
</Setting>
<Setting Name="Port" Type="System.Int32" Scope="User">
<Value Profile="(Default)">995</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{6D46F847-24F2-4883-8B0E-21386FFD0C96}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>bsmd.EMailReceiveService</RootNamespace>
<AssemblyName>bsmd.EMailReceiveService</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net">
<HintPath>packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
</Reference>
<Reference Include="OpenPop">
<HintPath>packages\OpenPop.NET.2.0.6.1102\lib\net40\OpenPop.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\bsmd.database\Properties\AssemblyProductInfo.cs">
<Link>Properties\AssemblyProductInfo.cs</Link>
</Compile>
<Compile Include="..\bsmd.database\Properties\AssemblyProjectInfo.cs">
<Link>Properties\AssemblyProjectInfo.cs</Link>
</Compile>
<Compile Include="..\bsmd.database\Properties\AssemblyProjectKeyInfo.cs">
<Link>Properties\AssemblyProjectKeyInfo.cs</Link>
</Compile>
<Compile Include="EmailReceiveService.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="EmailReceiveService.Designer.cs">
<DependentUpon>EmailReceiveService.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\bsmd.database\bsmd.database.csproj">
<Project>{19945af2-379b-46a5-b27a-303b5ec1d557}</Project>
<Name>bsmd.database</Name>
</ProjectReference>
<ProjectReference Include="..\bsmd.dbh\bsmd.dbh.csproj">
<Project>{df625ff0-2265-4686-9cb6-2a8511cb3b9d}</Project>
<Name>bsmd.dbh</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="readme.txt" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.3" targetFramework="net45" />
<package id="OpenPop.NET" version="2.0.6.1102" targetFramework="net45" />
</packages>

View File

@ -0,0 +1,11 @@
DB Connection string lokal:
Data Source=(localdb)\Projects;Initial Catalog=nsw;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False
Testaccount:
nsw@textbausteine.net
Passwort: 3kjksJSD343
Server: pop3.strato.de
Port: 995

View File

@ -79,7 +79,22 @@ namespace bsmd.database
return result; return result;
} }
public List<Message> GetToSendMessageList() public MessageCore GetHerbergFormMessage(Guid herbergFormGuid)
{
MessageCore aMessageCore = new MessageCore();
SqlCommand cmd = new SqlCommand();
aMessageCore.PrepareLoadCommand(cmd, Message.LoadFilter.HERBERG_FORMGUID, herbergFormGuid);
SqlDataReader reader = this.PerformCommand(cmd);
List<DatabaseEntity> cores = aMessageCore.LoadList(reader);
if (cores.Count > 1) _log.WarnFormat("Herberg form message: {0} cores found for guid {1}",
cores.Count, herbergFormGuid);
if(cores.Count > 0)
return (MessageCore) cores[0];
return null;
}
public List<DatabaseEntity> GetToSendMessageList()
{ {
Message aMessage = new Message(); Message aMessage = new Message();
SqlCommand cmd = new SqlCommand(); SqlCommand cmd = new SqlCommand();
@ -88,11 +103,12 @@ namespace bsmd.database
SqlDataReader reader = this.PerformCommand(cmd); SqlDataReader reader = this.PerformCommand(cmd);
List<DatabaseEntity> messages = aMessage.LoadList(reader); List<DatabaseEntity> messages = aMessage.LoadList(reader);
List<Message> result = new List<Message>();
foreach (Message message in messages)
result.Add(message);
this.LoadMessageDependencies(result); List<Message> messageList = new List<Message>();
foreach (Message message in messages)
messageList.Add(message);
List<DatabaseEntity> result = this.LoadMessageDependencies(messageList);
return result; return result;
} }
@ -112,32 +128,44 @@ namespace bsmd.database
return result; return result;
} }
public void Save(Message message) public void Save(DatabaseEntity entity)
{ {
SqlCommand cmd = new SqlCommand(); SqlCommand cmd = new SqlCommand();
message.PrepareSave(cmd); entity.PrepareSave(cmd);
int queryResult = this.PerformNonQuery(cmd); int queryResult = this.PerformNonQuery(cmd);
switch(queryResult) switch(queryResult)
{ {
case 1: case 1:
_log.InfoFormat("Message {0} saved", message.Id); break; _log.InfoFormat("Message {0} saved", entity.Id); break;
case 0: case 0:
_log.WarnFormat("Message {0} save affected no rows", message.Id); break; _log.WarnFormat("Message {0} save affected no rows", entity.Id); break;
case -1: case -1:
_log.WarnFormat("Message {0} save: error occurred", message.Id); break; _log.WarnFormat("Message {0} save: error occurred", entity.Id); break;
default: default:
_log.WarnFormat("Message {0} save affected {1} rows", message.Id, queryResult); break; _log.WarnFormat("Message {0} save affected {1} rows", entity.Id, queryResult); break;
} }
} }
public void Save(MessageCore core)
{
SqlCommand cmd = new SqlCommand();
core.PrepareSave(cmd);
int queryResult = this.PerformNonQuery(cmd);
if (queryResult == 1)
_log.InfoFormat("MessageCore {0} saved", core.Id);
else
_log.WarnFormat("MessageCore {0} save affected {1} rows", core.Id, queryResult);
}
#endregion #endregion
#region internal/private funcs #region internal/private funcs
internal void LoadMessageDependencies(List<Message> messageList) internal List<DatabaseEntity> LoadMessageDependencies(List<Message> messageList)
{ {
Dictionary<Guid, MessageCore> messageCoreDict = this.GetToSendMessageCoreList(); Dictionary<Guid, MessageCore> messageCoreDict = this.GetToSendMessageCoreList();
Dictionary<Guid, ReportingParty> reportingPartyDict = this.GetReportingPartyDict(); Dictionary<Guid, ReportingParty> reportingPartyDict = this.GetReportingPartyDict();
List<DatabaseEntity> result = new List<DatabaseEntity>();
// Zuordnung MessageCore,Zuordnung Reporting party // Zuordnung MessageCore,Zuordnung Reporting party
Message.AssignReportingParties(messageList, reportingPartyDict); Message.AssignReportingParties(messageList, reportingPartyDict);
@ -159,15 +187,17 @@ namespace bsmd.database
List<DatabaseEntity> statList = msgClass.LoadList(reader); List<DatabaseEntity> statList = msgClass.LoadList(reader);
if (statList.Count > 0) message.DerivedMessage = statList[0]; if (statList.Count > 0) message.DerivedMessage = statList[0];
((IMessageClass)msgClass).MessageHeader = message; ((IMessageClass)msgClass).MessageHeader = message;
this.LoadDependingLists(msgClass);
result.Add(msgClass);
} }
else else
{ {
_log.ErrorFormat("cannot create a message class for notification type {0}", message.MessageNotificationClass); _log.ErrorFormat("cannot create a message class for notification type {0}", message.MessageNotificationClass);
} result.Add(message);
}
this.LoadDependingLists(message);
} }
return result;
} }
#region CreateMessage() #region CreateMessage()
@ -206,9 +236,10 @@ namespace bsmd.database
case Message.NotificationClass.HAZA: case Message.NotificationClass.HAZA:
case Message.NotificationClass.HAZD: case Message.NotificationClass.HAZD:
default:
_log.WarnFormat("CreateMessage: message type {0} is not supported", notificationClass.ToString()); _log.WarnFormat("CreateMessage: message type {0} is not supported", notificationClass.ToString());
break; break;
default:
break; // VISIT, TRANSIT
} }
return result; return result;
} }

View File

@ -17,10 +17,24 @@ namespace bsmd.database
public abstract class DatabaseEntity public abstract class DatabaseEntity
{ {
protected Guid? id; protected Guid? id;
protected string tablename; protected string tablename;
/// <summary>
/// Nachrichtentyp der abgeleiteten Meldeklassen
/// </summary>
public Message.NotificationClass MessageNotificationClass { get; set; }
/// <summary>
/// Referenz zur eigentlichen Schiffankunft
/// </summary>
public MessageCore MessageCore { get; set; }
/// <summary>
/// Status für Services
/// </summary>
public Message.BSMDStatus InternalStatus { get; set; }
/// <summary> /// <summary>
/// SQL Table name to construct queries /// SQL Table name to construct queries
/// </summary> /// </summary>

View File

@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace bsmd.database namespace bsmd.database
{ {
interface IMessageClass public interface IMessageClass
{ {
Message MessageHeader { get; set; } Message MessageHeader { get; set; }
} }

View File

@ -14,8 +14,7 @@ namespace bsmd.database
public class Message : DatabaseEntity public class Message : DatabaseEntity
{ {
private Guid messageHeaderId; private Guid messageHeaderId;
private Guid? messageCoreId; private Guid? messageCoreId;
private MessageCore messageCore;
private Guid? reportingPartyId; private Guid? reportingPartyId;
private ReportingParty reportingParty; private ReportingParty reportingParty;
private DateTime? created; private DateTime? created;
@ -52,7 +51,8 @@ namespace bsmd.database
WAS_ID, WAS_ID,
WDSP_ID, WDSP_ID,
BPOL_ID, BPOL_ID,
SEC_ID SEC_ID,
HERBERG_FORMGUID
} }
/// <summary> /// <summary>
@ -93,12 +93,7 @@ namespace bsmd.database
/// <summary> /// <summary>
/// Dieser Wert wird vom NSW / HIS vergeben /// Dieser Wert wird vom NSW / HIS vergeben
/// </summary> /// </summary>
public string ClientRequestId { set; get; } public string ClientRequestId { set; get; }
/// <summary>
/// Referenz zur eigentlichen Schiffankunft
/// </summary>
public MessageCore MessageCore { get { return this.messageCore; } }
public Guid? MessageId { get; set; } public Guid? MessageId { get; set; }
@ -114,22 +109,12 @@ namespace bsmd.database
public MessageStatus? Status { get; set; } public MessageStatus? Status { get; set; }
public DateTime? Created { get { return this.created; } } public DateTime? Created { get { return this.created; } }
/// <summary>
/// Nachrichtentyp der abgeleiteten Meldeklassen
/// </summary>
public NotificationClass MessageNotificationClass { get; set; }
/// <summary> /// <summary>
/// Der Meldende /// Der Meldende
/// </summary> /// </summary>
public ReportingParty ReportingParty { get { return this.reportingParty; } } public ReportingParty ReportingParty { get { return this.reportingParty; } }
/// <summary>
/// Status für Services
/// </summary>
public BSMDStatus InternalStatus { get; set; }
/// <summary> /// <summary>
/// die zur Kommunikation zu verwendende HIS Schnittstelle /// die zur Kommunikation zu verwendende HIS Schnittstelle
@ -153,7 +138,7 @@ namespace bsmd.database
#endregion #endregion
#region IDatabaseEntity implementation #region IDatabaseEntity implementation
public override void PrepareSave(IDbCommand cmdParam) public override void PrepareSave(IDbCommand cmdParam)
{ {
@ -280,7 +265,7 @@ namespace bsmd.database
foreach (Message message in messages) foreach (Message message in messages)
{ {
if (message.messageCoreId.HasValue && messageCores.ContainsKey(message.messageCoreId.Value)) if (message.messageCoreId.HasValue && messageCores.ContainsKey(message.messageCoreId.Value))
message.messageCore = messageCores[message.messageCoreId.Value]; message.MessageCore = messageCores[message.messageCoreId.Value];
} }
} }

View File

@ -21,7 +21,7 @@ namespace bsmd.database
this.tablename = "[dbo].[MessageCore]"; this.tablename = "[dbo].[MessageCore]";
} }
#region Properties #region Properties
public string VisitId { get; set; } public string VisitId { get; set; }
@ -43,6 +43,10 @@ namespace bsmd.database
public Message.NSWProvider InitialHIS { get; set; } public Message.NSWProvider InitialHIS { get; set; }
public Guid? HerbergFormGuid { get; set; }
public Guid? HerbergFormTemplateGuid { get; set; }
#endregion #endregion
public override void PrepareSave(IDbCommand cmd) public override void PrepareSave(IDbCommand cmd)
@ -74,12 +78,16 @@ namespace bsmd.database
else scmd.Parameters.AddWithValue("@P12", DBNull.Value); else scmd.Parameters.AddWithValue("@P12", DBNull.Value);
scmd.Parameters.AddWithValue("@P13", this.BSMDStatus); scmd.Parameters.AddWithValue("@P13", this.BSMDStatus);
scmd.Parameters.AddWithValue("@P14", this.InitialHIS); scmd.Parameters.AddWithValue("@P14", this.InitialHIS);
scmd.Parameters.AddWithNullableValue("@P15", this.HerbergFormGuid);
scmd.Parameters.AddWithNullableValue("@P16", this.HerbergFormTemplateGuid);
if (this.IsNew) if (this.IsNew)
{ {
string query = string.Format("INSERT INTO {0} (VisitId, TransitId, IMO, ENI, PoC, Portname, ETA, CustomerId, " + string query = string.Format("INSERT INTO {0} (VisitId, TransitId, IMO, ENI, PoC, Portname, ETA, CustomerId, " +
"Previous, Next, IsTransit, Wetris_zz_56_datensatz_id, BSMDStatus, InitialHIS) VALUES " + "Previous, Next, IsTransit, Wetris_zz_56_datensatz_id, BSMDStatus, InitialHIS, HerbergFormGuid, " +
"(@P1, @P2, @P3, @P4, @P5, @P6, @P7, @P8, @P9, @P10, @P11, @P12, @P13, @P14)", this.Tablename); "HerbergFormTemplateGuid) VALUES " +
"(@P1, @P2, @P3, @P4, @P5, @P6, @P7, @P8, @P9, @P10, @P11, @P12, @P13, @P14, @P15, @P16)",
this.Tablename);
scmd.CommandText = query; scmd.CommandText = query;
} }
else else
@ -87,7 +95,8 @@ namespace bsmd.database
scmd.Parameters.AddWithValue("@ID", this.Id); scmd.Parameters.AddWithValue("@ID", this.Id);
string query = string.Format("UPDATE {0} SET VisitId = @P1, TransitId = @P2, IMO = @P3, ENI = @P4, Poc = @P5, " + string query = string.Format("UPDATE {0} SET VisitId = @P1, TransitId = @P2, IMO = @P3, ENI = @P4, Poc = @P5, " +
"Portname = @P6, ETA = @P7, CustomerId = @P8, Previous = @P9, Next = @P10, IsTransit = @P11, " + "Portname = @P6, ETA = @P7, CustomerId = @P8, Previous = @P9, Next = @P10, IsTransit = @P11, " +
"Wetris_zz_56_datensatz_id = @P12, BSMDStatus = @P13, InitialHIS = @P14 WHERE Id = @ID", this.Tablename); "Wetris_zz_56_datensatz_id = @P12, BSMDStatus = @P13, InitialHIS = @P14, HerbergFormGuid = @P15, " +
"HerbergFormTemplateGuid = @P16 WHERE Id = @ID", this.Tablename);
} }
} }
@ -95,7 +104,8 @@ namespace bsmd.database
public override void PrepareLoadCommand(System.Data.IDbCommand cmd, Message.LoadFilter filter, params object[] criteria) public override void PrepareLoadCommand(System.Data.IDbCommand cmd, Message.LoadFilter filter, params object[] criteria)
{ {
string query = string.Format("SELECT Id, VisitId, TransitId, IMO, ENI, PoC, Portname, " + string query = string.Format("SELECT Id, VisitId, TransitId, IMO, ENI, PoC, Portname, " +
"ETA, CustomerId, Previous, Next, IsTransit, Wetris_zz_56_datensatz_id, BSMDStatus, InitialHIS FROM {0} ", "ETA, CustomerId, Previous, Next, IsTransit, Wetris_zz_56_datensatz_id, BSMDStatus, InitialHIS, " +
"HerbergFormGuid, HerbergFormTemplateGuid FROM {0} ",
this.Tablename); this.Tablename);
switch (filter) switch (filter)
@ -103,7 +113,13 @@ namespace bsmd.database
case Message.LoadFilter.WETRIS_SHIP_ID: case Message.LoadFilter.WETRIS_SHIP_ID:
{ {
query += "WHERE Wetris_zz_56_datensatz_id = @WETRIS"; query += "WHERE Wetris_zz_56_datensatz_id = @WETRIS";
((SqlCommand)cmd).Parameters.AddWithValue("WETRIS", criteria[0]); ((SqlCommand)cmd).Parameters.AddWithValue("@WETRIS", criteria[0]);
break;
}
case Message.LoadFilter.HERBERG_FORMGUID:
{
query += "WHERE HerbergFormGuid = @HFG";
((SqlCommand)cmd).Parameters.AddWithValue("@HFG", criteria[0]);
break; break;
} }
case Message.LoadFilter.ALL: case Message.LoadFilter.ALL:
@ -135,6 +151,8 @@ namespace bsmd.database
if (!reader.IsDBNull(12)) core.wetris_zz_56_datensatz_id = reader.GetInt32(12); if (!reader.IsDBNull(12)) core.wetris_zz_56_datensatz_id = reader.GetInt32(12);
core.BSMDStatus = (Message.BSMDStatus) Enum.ToObject(typeof(Message.BSMDStatus), reader.GetByte(13)); core.BSMDStatus = (Message.BSMDStatus) Enum.ToObject(typeof(Message.BSMDStatus), reader.GetByte(13));
core.InitialHIS = (Message.NSWProvider) Enum.ToObject(typeof(Message.NSWProvider), reader.GetByte(14)); core.InitialHIS = (Message.NSWProvider) Enum.ToObject(typeof(Message.NSWProvider), reader.GetByte(14));
if (!reader.IsDBNull(15)) core.HerbergFormGuid = reader.GetGuid(15);
if (!reader.IsDBNull(16)) core.HerbergFormTemplateGuid = reader.GetGuid(16);
result.Add(core); result.Add(core);
} }

View File

@ -1,7 +1,7 @@
using System.Reflection; using System.Reflection;
[assembly: AssemblyCompany("Informatikbüro Daniel Schick")] [assembly: AssemblyCompany("Informatikbüro Daniel Schick")]
[assembly: AssemblyProduct("bsmd.database")] [assembly: AssemblyProduct("BSMD NSW interface")]
[assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyInformationalVersion("1.0.2")]
[assembly: AssemblyCopyright("Copyright © 2014-2015 Informatikbüro Daniel Schick. All rights reserved.")] [assembly: AssemblyCopyright("Copyright © 2014-2015 Informatikbüro Daniel Schick. All rights reserved.")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]

View File

@ -4,6 +4,6 @@
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.1.*")] [assembly: AssemblyVersion("1.0.2.*")]
// wenn das nicht auskommentiert wird erhalten wir eine Warnung // wenn das nicht auskommentiert wird erhalten wir eine Warnung
// [assembly: AssemblyFileVersion("1.0.0.*")] // [assembly: AssemblyFileVersion("1.0.0.*")]

View File

@ -96,7 +96,6 @@
<Compile Include="WasteDisposalServiceProvider.cs" /> <Compile Include="WasteDisposalServiceProvider.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="App.Config" />
<None Include="..\bsmdKey.snk" /> <None Include="..\bsmdKey.snk" />
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>

View File

@ -12,38 +12,19 @@ namespace bsmd.dbh.ResponseService
[ServiceContract] [ServiceContract]
public interface IResponseService public interface IResponseService
{ {
/*
[OperationContract] [OperationContract]
string GetData(int value); string GetData(int value);
*/
/// <summary> /// <summary>
/// Da die Schnittstelle nur mit einem .xsd definiert war ist die Signatur der Methode fraglich /// Da die Schnittstelle nur mit einem .xsd definiert war ist die Signatur der Methode fraglich
/// Sicher ist Void, weniger sicher der Namen und der Name des Parameters. Dessen Type allerdings schon. /// Sicher ist Void, weniger sicher der Namen und der Name des Parameters. Dessen Type allerdings schon.
/// </summary> /// </summary>
[OperationContract] [OperationContract]
[XmlSerializerFormatAttribute()]
void NSWResponse(bsmd.dbh.response.Root root); void NSWResponse(bsmd.dbh.response.Root root);
} }
// Use a data contract as illustrated in the sample below to add composite types to service operations.
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
} }

View File

@ -6,14 +6,9 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("bsmd.dbh.ResponseService")] [assembly: AssemblyTitle("bsmd.dbh.ResponseService")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("Webservice zum Empfang der NSW Response Nachrichten von dbh")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("bsmd.dbh.ResponseService")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
// Setting ComVisible to false makes the types in this assembly not visible // Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from // to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type. // COM, set the ComVisible attribute to true on that type.
@ -22,15 +17,3 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM // The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("f9d61dd1-3f43-4c8b-83b1-b778d28a5367")] [assembly: Guid("f9d61dd1-3f43-4c8b-83b1-b778d28a5367")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -1 +1 @@
<%@ ServiceHost Language="C#" Debug="true" Service="bsmd.dbh.ResponseService.ResponseService" CodeBehind="Service1.svc.cs" %> <%@ ServiceHost Language="C#" Debug="true" Service="bsmd.dbh.ResponseService.ResponseService" CodeBehind="ResponseService.svc.cs" %>

View File

@ -1,11 +1,4 @@
using System; using log4net;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using log4net;
namespace bsmd.dbh.ResponseService namespace bsmd.dbh.ResponseService
{ {
@ -13,18 +6,12 @@ namespace bsmd.dbh.ResponseService
// NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging. // NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
public class ResponseService : IResponseService public class ResponseService : IResponseService
{ {
private ILog _log = LogManager.GetLogger("dbh ResponseService"); private ILog _log = LogManager.GetLogger("dbh ResponseService");
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public void NSWResponse(bsmd.dbh.response.Root root) public void NSWResponse(bsmd.dbh.response.Root root)
{ {
_log.Info("response received!"); _log.Info("response received!");
Response.ProcessResponse(root); Response.ProcessResponse(root, Properties.Settings.Default.DBConnectionString);
} }
} }
} }

View File

@ -1,6 +1,11 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<configuration> <configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="bsmd.dbh.ResponseService.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<appSettings> <appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings> </appSettings>
@ -32,5 +37,11 @@
--> -->
<directoryBrowse enabled="true"/> <directoryBrowse enabled="true"/>
</system.webServer> </system.webServer>
<applicationSettings>
<bsmd.dbh.ResponseService.Properties.Settings>
<setting name="DBConnectionString" serializeAs="String">
<value>replace me!</value>
</setting>
</bsmd.dbh.ResponseService.Properties.Settings>
</applicationSettings>
</configuration> </configuration>

View File

@ -63,9 +63,25 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="ResponseService.svc" /> <Content Include="ResponseService.svc" />
<Content Include="Web.config" /> <Content Include="Web.config">
<SubType>Designer</SubType>
</Content>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\bsmd.database\Properties\AssemblyProductInfo.cs">
<Link>Properties\AssemblyProductInfo.cs</Link>
</Compile>
<Compile Include="..\bsmd.database\Properties\AssemblyProjectInfo.cs">
<Link>Properties\AssemblyProjectInfo.cs</Link>
</Compile>
<Compile Include="..\bsmd.database\Properties\AssemblyProjectKeyInfo.cs">
<Link>Properties\AssemblyProjectKeyInfo.cs</Link>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="ResponseService.svc.cs"> <Compile Include="ResponseService.svc.cs">
<DependentUpon>ResponseService.svc</DependentUpon> <DependentUpon>ResponseService.svc</DependentUpon>
</Compile> </Compile>
@ -77,6 +93,17 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="packages.config" /> <Content Include="packages.config" />
<Content Include="..\bsmdKey.snk">
<Link>bsmdKey.snk</Link>
</Content>
<Content Include="log4net.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<SubType>Designer</SubType>
</Content>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<None Include="Web.Debug.config"> <None Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon> <DependentUpon>Web.config</DependentUpon>
</None> </None>
@ -98,6 +125,12 @@
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>..\bsmdKey.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />

View File

@ -0,0 +1,22 @@
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>
</configSections>
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
</root>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender" >
<param name="File" value="E:\Temp\dbh.Response.log" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
</log4net>
</configuration>

View File

@ -13,7 +13,6 @@ using System.Xml.Serialization;
// //
// This source code was auto-generated by xsd, Version=4.0.30319.1. // This source code was auto-generated by xsd, Version=4.0.30319.1.
// //
namespace bsmd.dbh.response namespace bsmd.dbh.response
{ {
@ -743,4 +742,4 @@ namespace bsmd.dbh.response
ERROR, ERROR,
} }
} }

View File

@ -0,0 +1,296 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid XML Studio - FREE Community Edition 7.0.3.780 (http://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="Version">
<xs:annotation>
<xs:documentation>Version number of schema</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1" />
<xs:maxLength value="5" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="MessageId" type="xs:string" />
<xs:element minOccurs="0" name="VisitId">
<xs:annotation>
<xs:documentation>Required when TransitId is missing and field "Type" is not "VISIT or "TRANSIT"</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="(DE)([A-Z]{3})-([0-9]{4})-([A-Z]{6})" />
<xs:length value="17" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element minOccurs="0" name="TransitId">
<xs:annotation>
<xs:documentation>Required when VisitId is missing and field "Type" is not "VISIT or "TRANSIT"</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="(ZZNOK)-([0-9]{4})-([A-Z]{6})" />
<xs:length value="17" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Timestamp" type="xs:dateTime">
<xs:annotation>
<xs:documentation>Timestamp, when the message is sent</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="Type">
<xs:annotation>
<xs:documentation>The message type (should be the same as in the request message):
- VISIT: Creates a new declaration with the application for a VisitId. It's allowed to send further data in one or more reporting classes
- TRANSIT: same with TransitId
- DATA: Only data for one or more reporting classes are included
- RESET: The data of one or more reporting classes are deleted
- CANCEL: The whole declaration is cancelled</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="VISIT" />
<xs:enumeration value="TRANSIT" />
<xs:enumeration value="DATA" />
<xs:enumeration value="RESET" />
<xs:enumeration value="CANCEL" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element minOccurs="0" name="ReportingClassesFull">
<xs:annotation>
<xs:documentation>Reporting classes that are received with all necessary data.</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="ReportingClass">
<xs:annotation>
<xs:documentation>The code of a reporting class.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="NOA_NOD" />
<xs:enumeration value="ATA" />
<xs:enumeration value="ATD" />
<xs:enumeration value="SEC" />
<xs:enumeration value="POBA" />
<xs:enumeration value="POBD" />
<xs:enumeration value="NAME" />
<xs:enumeration value="TIEFA" />
<xs:enumeration value="TIEFD" />
<xs:enumeration value="BKRA" />
<xs:enumeration value="BKRD" />
<xs:enumeration value="STAT" />
<xs:enumeration value="LADG" />
<xs:enumeration value="INFO" />
<xs:enumeration value="SERV" />
<xs:enumeration value="PRE72H" />
<xs:enumeration value="MDH" />
<xs:enumeration value="WAS" />
<xs:enumeration value="CREW" />
<xs:enumeration value="PAS" />
<xs:enumeration value="BPOL" />
<xs:enumeration value="TOWA" />
<xs:enumeration value="TOWD" />
<xs:enumeration value="HAZA" />
<xs:enumeration value="HAZD" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element minOccurs="0" name="ReportingClassesPartial">
<xs:annotation>
<xs:documentation>Reporting classes that are received with some data missing (see Messages for errors/violations).</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="ReportingClass">
<xs:annotation>
<xs:documentation>The code of a reporting class.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="NOA_NOD" />
<xs:enumeration value="ATA" />
<xs:enumeration value="ATD" />
<xs:enumeration value="SEC" />
<xs:enumeration value="POBA" />
<xs:enumeration value="POBD" />
<xs:enumeration value="NAME" />
<xs:enumeration value="TIEFA" />
<xs:enumeration value="TIEFD" />
<xs:enumeration value="BKRA" />
<xs:enumeration value="BKRD" />
<xs:enumeration value="STAT" />
<xs:enumeration value="LADG" />
<xs:enumeration value="INFO" />
<xs:enumeration value="SERV" />
<xs:enumeration value="PRE72H" />
<xs:enumeration value="MDH" />
<xs:enumeration value="WAS" />
<xs:enumeration value="CREW" />
<xs:enumeration value="PAS" />
<xs:enumeration value="BPOL" />
<xs:enumeration value="TOWA" />
<xs:enumeration value="TOWD" />
<xs:enumeration value="HAZA" />
<xs:enumeration value="HAZD" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element minOccurs="0" name="ReportingClassesError">
<xs:annotation>
<xs:documentation>Reporting classes that are received with some data missing (see Messages for errors/violations).</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="ReportingClass">
<xs:annotation>
<xs:documentation>The code of a reporting class.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="NOA_NOD" />
<xs:enumeration value="ATA" />
<xs:enumeration value="ATD" />
<xs:enumeration value="SEC" />
<xs:enumeration value="POBA" />
<xs:enumeration value="POBD" />
<xs:enumeration value="NAME" />
<xs:enumeration value="TIEFA" />
<xs:enumeration value="TIEFD" />
<xs:enumeration value="BKRA" />
<xs:enumeration value="BKRD" />
<xs:enumeration value="STAT" />
<xs:enumeration value="LADG" />
<xs:enumeration value="INFO" />
<xs:enumeration value="SERV" />
<xs:enumeration value="PRE72H" />
<xs:enumeration value="MDH" />
<xs:enumeration value="WAS" />
<xs:enumeration value="CREW" />
<xs:enumeration value="PAS" />
<xs:enumeration value="BPOL" />
<xs:enumeration value="TOWA" />
<xs:enumeration value="TOWD" />
<xs:enumeration value="HAZA" />
<xs:enumeration value="HAZD" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element minOccurs="0" name="ReportingClassesResetted">
<xs:annotation>
<xs:documentation>Reporting classes that are resetted (due to a message with Type RESET).</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="ReportingClass">
<xs:annotation>
<xs:documentation>The code of a reporting class.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="NOA_NOD" />
<xs:enumeration value="ATA" />
<xs:enumeration value="ATD" />
<xs:enumeration value="SEC" />
<xs:enumeration value="POBA" />
<xs:enumeration value="POBD" />
<xs:enumeration value="NAME" />
<xs:enumeration value="TIEFA" />
<xs:enumeration value="TIEFD" />
<xs:enumeration value="BKRA" />
<xs:enumeration value="BKRD" />
<xs:enumeration value="STAT" />
<xs:enumeration value="LADG" />
<xs:enumeration value="INFO" />
<xs:enumeration value="SERV" />
<xs:enumeration value="PRE72H" />
<xs:enumeration value="MDH" />
<xs:enumeration value="WAS" />
<xs:enumeration value="CREW" />
<xs:enumeration value="PAS" />
<xs:enumeration value="BPOL" />
<xs:enumeration value="TOWA" />
<xs:enumeration value="TOWD" />
<xs:enumeration value="HAZA" />
<xs:enumeration value="HAZD" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Messages">
<xs:annotation>
<xs:documentation>Errors, Violations, etc.</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="Message">
<xs:complexType>
<xs:sequence>
<xs:element name="ID">
<xs:annotation>
<xs:documentation>ID (given from NSW)</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="3" />
<xs:maxLength value="6" />
<xs:pattern value="([A-Z]{0,3}[1-9][0-9]{2})" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Type">
<xs:annotation>
<xs:documentation>Type of Message (functional error, process error in report, process error in message basket, process error during status request, or violation)</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="INFO" />
<xs:enumeration value="WARNING" />
<xs:enumeration value="VIOLATION" />
<xs:enumeration value="ERROR" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Location">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1" />
<xs:maxLength value="32" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Text">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1" />
<xs:maxLength value="255" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -9,94 +9,238 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using log4net;
using bsmd.database; using bsmd.database;
using bsmd.dbh.request; //using bsmd.dbh.request;
using bsmd.dbh.DBHWebReference;
namespace bsmd.dbh namespace bsmd.dbh
{ {
public class Request public class Request
{ {
private static ILog _log = LogManager.GetLogger(typeof(Request));
public static bool SendMessage(Message aMessage) public static bool SendMessage(DatabaseEntity dbEntity)
{ {
if (dbEntity == null) return false;
if (aMessage == null) return false;
Message aMessage = null;
if (dbEntity.GetType().IsAssignableFrom(typeof(Message)))
{
aMessage = (Message)dbEntity;
}
else
{
IMessageClass msgClass = (IMessageClass)dbEntity;
aMessage = msgClass.MessageHeader;
}
// map message to dbh NSWRequest object // map message to dbh NSWRequest object
Root root = new Root(); Dbh_Osis_Answ_Ws client = new Dbh_Osis_Answ_Ws();
root.Version = "1.8";
root.ReportingParty = new RootReportingParty();
root.ReportingParty.RPCity = aMessage.ReportingParty.City;
root.ReportingParty.RPCountry = aMessage.ReportingParty.Country;
root.ReportingParty.RPEMail = aMessage.ReportingParty.EMail;
root.ReportingParty.RPFax = aMessage.ReportingParty.Fax;
root.ReportingParty.RPFirstName = aMessage.ReportingParty.FirstName;
root.ReportingParty.RPLastName = aMessage.ReportingParty.LastName;
root.ReportingParty.RPName = aMessage.ReportingParty.Name;
root.ReportingParty.RPPhone = aMessage.ReportingParty.Phone;
root.ReportingParty.RPPostalCode = aMessage.ReportingParty.PostalCode;
root.ReportingParty.RPStreetAndNumber = aMessage.ReportingParty.StreetAndNumber;
root.ReportingParty.RPTypeSpecified = aMessage.ReportingParty.ReportingPartyType.HasValue;
if (root.ReportingParty.RPTypeSpecified)
root.ReportingParty.RPType = (RootReportingPartyRPType) aMessage.ReportingParty.ReportingPartyType.Value;
root.Timestamp = DateTime.Now; RootReportingParty rp = new RootReportingParty();
rp.RPCity = aMessage.ReportingParty.City;
rp.RPCountry = aMessage.ReportingParty.Country;
rp.RPEMail = aMessage.ReportingParty.EMail;
rp.RPFax = aMessage.ReportingParty.Fax;
rp.RPFirstName = aMessage.ReportingParty.FirstName;
rp.RPLastName = aMessage.ReportingParty.LastName;
rp.RPName = aMessage.ReportingParty.Name;
rp.RPPhone = aMessage.ReportingParty.Phone;
rp.RPPostalCode = aMessage.ReportingParty.PostalCode;
rp.RPStreetAndNumber = aMessage.ReportingParty.StreetAndNumber;
rp.RPTypeSpecified = aMessage.ReportingParty.ReportingPartyType.HasValue;
if (rp.RPTypeSpecified)
rp.RPType = (RootReportingPartyRPType)aMessage.ReportingParty.ReportingPartyType.Value;
switch(aMessage.MessageNotificationClass) DateTime timestamp = DateTime.Now;
string version = "1.9";
object item = null;
string senderReference = Guid.NewGuid().ToString(); // TODO
RootType rootType = RootType.DATA;
ItemChoiceType2 itemChoiceType2 = ItemChoiceType2.Visit; // ?
switch (aMessage.MessageNotificationClass)
{ {
#region VISIT
case Message.NotificationClass.VISIT: case Message.NotificationClass.VISIT:
{ {
root.Type = RootType.VISIT; RootVisit rootVisit = new RootVisit();
root.Item = new RootVisit(); rootType = RootType.VISIT;
if (aMessage.MessageCore.IMO != null) if (aMessage.MessageCore.IMO != null)
{ {
((RootVisit)root.Item).ItemElementName = ItemChoiceType.IMONumber; rootVisit.ItemElementName = ItemChoiceType.IMONumber;
((RootVisit)root.Item).Item = aMessage.MessageCore.IMO; rootVisit.Item = aMessage.MessageCore.IMO;
} }
else else
{ {
((RootVisit)root.Item).ItemElementName = ItemChoiceType.ENINumber; rootVisit.ItemElementName = ItemChoiceType.ENINumber;
((RootVisit)root.Item).Item = aMessage.MessageCore.ENI; rootVisit.Item = aMessage.MessageCore.ENI;
} }
((RootVisit)root.Item).PortOfCall = aMessage.MessageCore.PoC; rootVisit.PortOfCall = aMessage.MessageCore.PoC;
((RootVisit)root.Item).ETAPortOfCall = aMessage.MessageCore.ETA.Value; rootVisit.ETAPortOfCall = aMessage.MessageCore.ETA.Value;
item = rootVisit;
break; break;
} }
#endregion
#region TRANSIT
case Message.NotificationClass.TRANSIT: case Message.NotificationClass.TRANSIT:
root.Type = RootType.TRANSIT;
root.Item = new RootTransit();
if (aMessage.MessageCore.IMO != null)
{ {
((RootTransit)root.Item).ItemElementName = ItemChoiceType1.IMONumber; RootTransit rootTransit = new RootTransit();
((RootTransit)root.Item).Item = aMessage.MessageCore.IMO; rootType = RootType.TRANSIT;
if (aMessage.MessageCore.IMO != null)
{
rootTransit.ItemElementName = ItemChoiceType1.IMONumber;
rootTransit.Item = aMessage.MessageCore.IMO;
}
else
{
rootTransit.ItemElementName = ItemChoiceType1.ENINumber;
rootTransit.Item = aMessage.MessageCore.ENI;
}
rootTransit.ETAKielCanal = aMessage.MessageCore.ETA.Value;
item = rootTransit;
break;
} }
else #endregion
#region NOA_NOD
case Message.NotificationClass.NOA_NOD:
{ {
((RootTransit)root.Item).ItemElementName = ItemChoiceType1.ENINumber; NOA_NOD noa_nod = dbEntity as NOA_NOD;
((RootTransit)root.Item).Item = aMessage.MessageCore.ENI; if (noa_nod != null)
{
RootNOA_NOD rootNoaNod = new RootNOA_NOD();
rootType = RootType.DATA;
if (noa_nod.ETAToNextPort.HasValue)
rootNoaNod.ETAToNextPort = noa_nod.ETAToNextPort.Value;
rootNoaNod.ETAToNextPortSpecified = noa_nod.ETAToNextPort.HasValue;
if (noa_nod.ETDFromLastPort.HasValue)
rootNoaNod.ETDFromLastPort = noa_nod.ETDFromLastPort.Value;
rootNoaNod.ETDFromLastPortSpecified = noa_nod.ETDFromLastPort.HasValue;
rootNoaNod.LastPort = noa_nod.LastPort;
rootNoaNod.NextPort = noa_nod.NextPort;
ItemsChoiceType[] choiceArray = new ItemsChoiceType[3];
object[] choices = new object[3];
choiceArray[0] = ItemsChoiceType.CallPurpose;
RootNOA_NODCallPurpose rnncp = new RootNOA_NODCallPurpose();
if (noa_nod.CallPurposeCode.HasValue)
rnncp.CallPurposeCode = noa_nod.CallPurposeCode.Value;
rnncp.CallPurposeDescription = noa_nod.CallPurposeDescription;
choices[0] = rnncp;
if (noa_nod.ETAToKielCanal.HasValue)
{
choiceArray[1] = ItemsChoiceType.ETAToKielCanal;
choices[1] = noa_nod.ETAToKielCanal.Value;
}
if (noa_nod.ETAToPortOfCall.HasValue)
{
choiceArray[1] = ItemsChoiceType.ETAToPortOfCall;
choices[1] = noa_nod.ETAToPortOfCall.Value;
}
if (noa_nod.ETDFromKielCanal.HasValue)
{
choiceArray[2] = ItemsChoiceType.ETDFromKielCanal;
choices[2] = noa_nod.ETDFromKielCanal.Value;
}
if (noa_nod.ETDFromPortOfCall.HasValue)
{
choiceArray[2] = ItemsChoiceType.ETDFromPortOfCall;
choices[2] = noa_nod.ETDFromPortOfCall.Value;
}
item = rootNoaNod;
}
break;
} }
#endregion
((RootTransit)root.Item).ETAKielCanal = aMessage.MessageCore.ETA.Value; #region ATA
case Message.NotificationClass.ATA:
{
ATA ata = dbEntity as ATA;
if (ata != null)
{
RootATA rootATA = new RootATA();
rootType = RootType.DATA;
rootATA.ATAPortOfCall = ata.ATAPortOfCall.Value;
item = rootATA;
}
break;
}
#endregion
break; #region ATD
case Message.NotificationClass.ATD:
{
ATD atd = dbEntity as ATD;
if (atd != null)
{
RootATD rootATD = new RootATD();
rootType = RootType.DATA;
rootATD.ATDPortOfCall = atd.ATDPortOfCall.Value;
item = rootATD;
}
break;
}
#endregion
case Message.NotificationClass.STAT: #region BPOL
case Message.NotificationClass.BPOL:
{
BPOL bpol = dbEntity as BPOL;
if (bpol != null)
{
RootBPOL rootBPOL = new RootBPOL();
rootType = RootType.DATA;
RootBPOLPortOfItinerary[] poiArray = new RootBPOLPortOfItinerary[bpol.PortOfItineraries.Count];
rootBPOL.PortOfItinerary = poiArray;
break; for (int i = 0; i < bpol.PortOfItineraries.Count; i++)
{
RootBPOLPortOfItinerary port = new RootBPOLPortOfItinerary();
if (bpol.PortOfItineraries[i].PortOfItineraryETA.HasValue)
port.PortOfItineraryETA = bpol.PortOfItineraries[i].PortOfItineraryETA.Value;
port.PortOfItineraryName = bpol.PortOfItineraries[i].PortOfItineraryName;
poiArray[i] = port;
}
if (bpol.StowawaysOnBoard.HasValue)
rootBPOL.StowawayOnBoard = bpol.StowawaysOnBoard.Value ?
RootBPOLStowawayOnBoard.Y : RootBPOLStowawayOnBoard.N;
item = rootBPOL;
}
break;
}
#endregion
default: default:
throw new NotImplementedException("sending message type not implemented yet!"); {
_log.ErrorFormat("DBH send message: message type {0} not implemented", aMessage.MessageNotificationClass);
break;
}
} }
// send object // send object
string result = client.Root(version, timestamp, Properties.Settings.Default.Sender, senderReference, rootType,
item, itemChoiceType2, null, rp, null, null);
return false; return false;
} }

View File

@ -10,34 +10,74 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using bsmd.database; using bsmd.database;
using log4net;
namespace bsmd.dbh namespace bsmd.dbh
{ {
public class Response public class Response
{ {
public static void ProcessResponse(response.Root response) private static ILog _log = LogManager.GetLogger("dbh Response");
public static void ProcessResponse(response.Root response, string connectionString)
{ {
_log.InfoFormat("processing message type {0}, version {1}", response.Type, response.Version);
switch(response.Type) if (DBManager.Instance.Connect(connectionString))
{ {
case dbh.response.RootType.VISIT:
break; // Status zu den jeweiligen Nachrichten. Bei uns sollte die Anzahl hier immer 1 sein, da wir die Dinger
case dbh.response.RootType.TRANSIT: // einzeln verschicken.
for (int i = 0; i < response.Messages.Length; i++)
{
switch (response.Messages[i].Type)
{
case dbh.response.RootMessageType.ERROR:
MessageError messageError = new MessageError();
messageError.ErrorText = response.Messages[i].Text;
// messageError.ErrorCode =
break;
case dbh.response.RootType.CANCEL:
break; break;
case dbh.response.RootType.RESET: case dbh.response.RootMessageType.VIOLATION:
break;
case dbh.response.RootType.DATA:
break; break;
case dbh.response.RootMessageType.WARNING:
case dbh.response.RootMessageType.INFO:
default:
break;
}
}
switch (response.Type)
{
case dbh.response.RootType.VISIT:
break;
case dbh.response.RootType.TRANSIT:
break;
case dbh.response.RootType.CANCEL:
break;
case dbh.response.RootType.RESET:
break;
case dbh.response.RootType.DATA:
break;
}
DBManager.Instance.Disconnect();
}
else
{
_log.Fatal("cannot connect to database");
} }
} }
} }

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="bsmd.dbh.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<bsmd.dbh.Properties.Settings>
<setting name="bsmd_dbh_DBHWebReference_Dbh_Osis_Answ_Ws" serializeAs="String">
<value>https://edi-gate.dbh.de/test/bsmd-soap</value>
</setting>
<setting name="Sender" serializeAs="String">
<value>00007009</value>
</setting>
</bsmd.dbh.Properties.Settings>
</userSettings>
</configuration>

View File

@ -41,6 +41,8 @@
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.EnterpriseServices" />
<Reference Include="System.Web.Services" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
@ -60,8 +62,18 @@
<Compile Include="NSWRequest.cs" /> <Compile Include="NSWRequest.cs" />
<Compile Include="NSWResponse.cs" /> <Compile Include="NSWResponse.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="Request.cs" /> <Compile Include="Request.cs" />
<Compile Include="Response.cs" /> <Compile Include="Response.cs" />
<Compile Include="Web References\DBHWebReference\Reference.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Reference.map</DependentUpon>
</Compile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\bsmd.database\bsmd.database.csproj"> <ProjectReference Include="..\bsmd.database\bsmd.database.csproj">
@ -71,7 +83,45 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\bsmdKey.snk" /> <None Include="..\bsmdKey.snk" />
<None Include="app.config" />
<None Include="NSWResponse.xsd">
<SubType>Designer</SubType>
</None>
<None Include="packages.config" /> <None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<None Include="Web References\DBHWebReference\answ-osis-extern.wsdl" />
<None Include="Web References\DBHWebReference\NSWRequest.xsd">
<SubType>Designer</SubType>
</None>
<None Include="Web References\DBHWebReference\Reference.map">
<Generator>MSDiscoCodeGenerator</Generator>
<LastGenOutput>Reference.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Service References\" />
</ItemGroup>
<ItemGroup>
<WebReferences Include="Web References\" />
</ItemGroup>
<ItemGroup>
<WebReferenceUrl Include="E:\work\bsmd\nsw\dbh\answ-osis-extern.wsdl">
<UrlBehavior>Dynamic</UrlBehavior>
<RelPath>Web References\DBHWebReference\</RelPath>
<UpdateFromURL>E:\work\bsmd\nsw\dbh\answ-osis-extern.wsdl</UpdateFromURL>
<ServiceLocationURL>
</ServiceLocationURL>
<CachedDynamicPropName>
</CachedDynamicPropName>
<CachedAppSettingsObjectName>Settings</CachedAppSettingsObjectName>
<CachedSettingsPropName>bsmd_dbh_DBHWebReference_Dbh_Osis_Answ_Ws</CachedSettingsPropName>
</WebReferenceUrl>
</ItemGroup>
<ItemGroup>
<Content Include="readme.txt" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@ -0,0 +1,8 @@
Um etwas mehr Kontrolle über die Erzeugung von Klassen aus .xsd Dateien zu haben verwende ich nicht
das mitgelieferte xsd.exe sondern ein VS Plugin http://xsd2code.codeplex.com/
Es wird über Kontext-Menü auf der XSD Datei gestartet. Deshalb ist diese auch hier im Projekt enthalten.
Damit man einen Web-Service erhält, der nicht die private Felder sondern die Properties der
generierten Klasse verwendet, muss man
[OperationContract] und [XmlSerializerFormatAttribute()]
auf der Interface-Methode verwenden.

View File

@ -37,6 +37,12 @@
<setting name="ServerAddress" serializeAs="String"> <setting name="ServerAddress" serializeAs="String">
<value>https://www.fleettracker.de/api/1.0/WSAPIFormData.php</value> <value>https://www.fleettracker.de/api/1.0/WSAPIFormData.php</value>
</setting> </setting>
<setting name="CompanyGuid" serializeAs="String">
<value>f2747e67-0043-43e4-b6a9-1ed3bf9265e4</value>
</setting>
<setting name="ClientGuid" serializeAs="String">
<value>76994eae-48de-44d4-a86d-6508e2e03dcf</value>
</setting>
</bsmd.herberg.FormService.Properties.Settings> </bsmd.herberg.FormService.Properties.Settings>
</userSettings> </userSettings>
<system.serviceModel> <system.serviceModel>

View File

@ -43,6 +43,10 @@ namespace bsmd.herberg.FormService
this.EventLog.WriteEntry("NSW Send Service started.", EventLogEntryType.Information); this.EventLog.WriteEntry("NSW Send Service started.", EventLogEntryType.Information);
} }
protected override void OnStop()
{
}
public void Init(string[] args) public void Init(string[] args)
{ {
this._timer = new Timer(); this._timer = new Timer();
@ -50,11 +54,7 @@ namespace bsmd.herberg.FormService
this._timer.Elapsed += _timer_Elapsed; this._timer.Elapsed += _timer_Elapsed;
this._timer.Enabled = true; this._timer.Enabled = true;
} }
protected override void OnStop()
{
}
void _timer_Elapsed(object sender, ElapsedEventArgs e) void _timer_Elapsed(object sender, ElapsedEventArgs e)
{ {
@ -78,14 +78,17 @@ namespace bsmd.herberg.FormService
body.apiIdentifier = new APIIdentifier(); body.apiIdentifier = new APIIdentifier();
// von Jan am 1.4.15: (April, April..) // von Jan am 1.4.15: (April, April..)
body.apiIdentifier.companyGuid = "f2747e67-0043-43e4-b6a9-1ed3bf9265e4"; body.apiIdentifier.companyGuid = Properties.Settings.Default.CompanyGuid.ToString();
body.apiIdentifier.clientGuid = "76994eae-48de-44d4-a86d-6508e2e03dcf"; body.apiIdentifier.clientGuid = Properties.Settings.Default.ClientGuid.ToString();
body.ffFolderTemplateTypeTag = "NSWAP"; body.ffFolderTemplateTypeTag = "NSWAD";
body.timeFrameRequestFilter = new TimeFrameRequestFilter(); body.timeFrameRequestFilter = new TimeFrameRequestFilter();
body.timeFrameRequestFilter.startDate = DateTime.Now; // TODO
body.timeFrameRequestFilter.startDate = DateTime.Now - new TimeSpan(30, 0, 0, 0); // last 30 days
body.timeFrameRequestFilter.startDateSpecified = true; body.timeFrameRequestFilter.startDateSpecified = true;
body.timeFrameRequestFilter.endDate = DateTime.Now + new TimeSpan(30, 0, 0, 0);
body.timeFrameRequestFilter.endDateSpecified = true;
// Liste der verfügbaren Formulare abholen // Liste der verfügbaren Formulare abholen
GetFormDataInfoListResponseData listReponse = client.GetFormDataInfoList(body); GetFormDataInfoListResponseData listReponse = client.GetFormDataInfoList(body);
@ -102,8 +105,8 @@ namespace bsmd.herberg.FormService
// Formular abholen // Formular abholen
GetFormDataRequestData formBody = new GetFormDataRequestData(); GetFormDataRequestData formBody = new GetFormDataRequestData();
formBody.apiIdentifier = new APIIdentifier(); formBody.apiIdentifier = new APIIdentifier();
formBody.apiIdentifier.companyGuid = Guid.NewGuid().ToString(); // TODO formBody.apiIdentifier.companyGuid = Properties.Settings.Default.CompanyGuid.ToString();
formBody.apiIdentifier.clientGuid = Guid.NewGuid().ToString(); // TODO formBody.apiIdentifier.clientGuid = Properties.Settings.Default.ClientGuid.ToString();
formBody.formGuid = dataSet.formGuid; formBody.formGuid = dataSet.formGuid;
@ -111,6 +114,24 @@ namespace bsmd.herberg.FormService
if (formResponse.success) if (formResponse.success)
{ {
// abgefragtes Formular in die DB speichern // abgefragtes Formular in die DB speichern
MessageCore aMessageCore = DBManager.Instance.GetHerbergFormMessage(new Guid(formBody.formGuid));
if (aMessageCore == null)
{
// neuen Anlaufeintrag (=MessageCore) erstellen
aMessageCore = new MessageCore();
aMessageCore.HerbergFormGuid = new Guid(formBody.formGuid);
// aMessageCore.HerbergFormTemplateGuid = formResponse.
aMessageCore.IMO = formResponse.imoNumber.ToString();
if (aMessageCore.IMO.Length > 7)
{
_log.WarnFormat("IMO {0} is longer than 7 chars, truncating!", aMessageCore.IMO);
aMessageCore.IMO = aMessageCore.IMO.Substring(0, 7);
}
DBManager.Instance.Save(aMessageCore);
}
// Änderungen im Formular übertragen und speichern
Util.UpdateFormCore(aMessageCore);
} }
else else

View File

@ -56,5 +56,29 @@ namespace bsmd.herberg.FormService.Properties {
return ((string)(this["bsmd_herberg_FormService_WebReference_WSAPIFormData"])); return ((string)(this["bsmd_herberg_FormService_WebReference_WSAPIFormData"]));
} }
} }
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("f2747e67-0043-43e4-b6a9-1ed3bf9265e4")]
public global::System.Guid CompanyGuid {
get {
return ((global::System.Guid)(this["CompanyGuid"]));
}
set {
this["CompanyGuid"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("76994eae-48de-44d4-a86d-6508e2e03dcf")]
public global::System.Guid ClientGuid {
get {
return ((global::System.Guid)(this["ClientGuid"]));
}
set {
this["ClientGuid"] = value;
}
}
} }
} }

View File

@ -11,5 +11,11 @@
<Setting Name="bsmd_herberg_FormService_WebReference_WSAPIFormData" Type="(Web Service URL)" Scope="Application"> <Setting Name="bsmd_herberg_FormService_WebReference_WSAPIFormData" Type="(Web Service URL)" Scope="Application">
<Value Profile="(Default)">http://www.fleettracker.de/api/1.0/WSAPIFormData.php</Value> <Value Profile="(Default)">http://www.fleettracker.de/api/1.0/WSAPIFormData.php</Value>
</Setting> </Setting>
<Setting Name="CompanyGuid" Type="System.Guid" Scope="User">
<Value Profile="(Default)">f2747e67-0043-43e4-b6a9-1ed3bf9265e4</Value>
</Setting>
<Setting Name="ClientGuid" Type="System.Guid" Scope="User">
<Value Profile="(Default)">76994eae-48de-44d4-a86d-6508e2e03dcf</Value>
</Setting>
</Settings> </Settings>
</SettingsFile> </SettingsFile>

View File

@ -0,0 +1,29 @@
//
// Class: Util
// Current CLR: 4.0.30319.34209
// System: Microsoft Visual Studio 10.0
// Author: dani
// Created: 4/13/2015 10:42:13 PM
//
// Copyright (c) 2015 Informatikbüro Daniel Schick. All rights reserved.
using System;
using System.Collections.Generic;
using log4net;
using bsmd.database;
namespace bsmd.herberg.FormService
{
public static class Util
{
private static ILog _log = LogManager.GetLogger(typeof(Util));
public static void UpdateFormCore(MessageCore core)
{
}
}
}

View File

@ -62,6 +62,7 @@
<DesignTimeSharedInput>True</DesignTimeSharedInput> <DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon> <DependentUpon>Settings.settings</DependentUpon>
</Compile> </Compile>
<Compile Include="Util.cs" />
<Compile Include="Web References\WebReference\Reference.cs"> <Compile Include="Web References\WebReference\Reference.cs">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>

View File

@ -23,6 +23,27 @@
<xs:documentation>Timestamp, when the message is sent</xs:documentation> <xs:documentation>Timestamp, when the message is sent</xs:documentation>
</xs:annotation> </xs:annotation>
</xs:element> </xs:element>
<xs:element name="Sender">
<xs:annotation>
<xs:documentation>The sender's ZKV number.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{8}" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element minOccurs="0" name="SenderReference">
<xs:annotation>
<xs:documentation>A customer reference that can be freely filled and will be send back in the following response. No checks are made on this field. When a new Visit- or TransitId is obtained, it should be used as a reference to match the response to its corresponding request.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="35" />
<xs:minLength value="0" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Type"> <xs:element name="Type">
<xs:annotation> <xs:annotation>
<xs:documentation>The message type: <xs:documentation>The message type:
@ -355,7 +376,7 @@
<xs:documentation>1 - 999</xs:documentation> <xs:documentation>1 - 999</xs:documentation>
</xs:annotation> </xs:annotation>
<xs:simpleType> <xs:simpleType>
<xs:restriction base="xs:integer"> <xs:restriction base="xs:int">
<xs:minInclusive value="1" /> <xs:minInclusive value="1" />
<xs:maxInclusive value="999" /> <xs:maxInclusive value="999" />
</xs:restriction> </xs:restriction>
@ -474,7 +495,7 @@
</xs:element> </xs:element>
<xs:element name="PortOfCallWhereCompleteSECNotified"> <xs:element name="PortOfCallWhereCompleteSECNotified">
<xs:annotation> <xs:annotation>
<xs:documentation>PortofCall where the complete information was notified (as UNECE LOCODE)</xs:documentation> <xs:documentation>PortofCall where the complete information was notified (requires the LOCODE of a german seaport, otherwise Violation 704 will occur)</xs:documentation>
</xs:annotation> </xs:annotation>
<xs:simpleType> <xs:simpleType>
<xs:restriction base="xs:string"> <xs:restriction base="xs:string">
@ -651,13 +672,13 @@
</xs:element> </xs:element>
<xs:element maxOccurs="10" name="LastTenPortFacilitiesCalled"> <xs:element maxOccurs="10" name="LastTenPortFacilitiesCalled">
<xs:annotation> <xs:annotation>
<xs:documentation>Last 10 port facilities called</xs:documentation> <xs:documentation>Last 10 port facilities called.</xs:documentation>
</xs:annotation> </xs:annotation>
<xs:complexType> <xs:complexType>
<xs:sequence> <xs:sequence>
<xs:element minOccurs="0" name="PortFacilityPortName"> <xs:element minOccurs="0" name="PortFacilityPortName">
<xs:annotation> <xs:annotation>
<xs:documentation>Port name</xs:documentation> <xs:documentation>Port name. Either port name and country or the LOCODE must be given or Violation 703 will occur.</xs:documentation>
</xs:annotation> </xs:annotation>
<xs:simpleType> <xs:simpleType>
<xs:restriction base="xs:string"> <xs:restriction base="xs:string">
@ -668,7 +689,7 @@
</xs:element> </xs:element>
<xs:element minOccurs="0" name="PortFacilityPortCountry"> <xs:element minOccurs="0" name="PortFacilityPortCountry">
<xs:annotation> <xs:annotation>
<xs:documentation>Country where port is located</xs:documentation> <xs:documentation>Country where port is located. Either port name and country or the LOCODE must be given or Violation 703 will occur.</xs:documentation>
</xs:annotation> </xs:annotation>
<xs:simpleType> <xs:simpleType>
<xs:restriction base="xs:string"> <xs:restriction base="xs:string">
@ -677,9 +698,9 @@
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
<xs:element name="PortFacilityPortLoCode"> <xs:element minOccurs="0" name="PortFacilityPortLoCode">
<xs:annotation> <xs:annotation>
<xs:documentation>LoCode of port where port facility is located (UNECE LOCODE)</xs:documentation> <xs:documentation>LoCode of port where port facility is located (UNECE LOCODE). Either port name and country or the LOCODE must be given or Violation 703 will occur.</xs:documentation>
</xs:annotation> </xs:annotation>
<xs:simpleType> <xs:simpleType>
<xs:restriction base="xs:string"> <xs:restriction base="xs:string">
@ -1173,9 +1194,9 @@
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
<xs:element name="ISMCompany"> <xs:element minOccurs="0" name="ISMCompany">
<xs:annotation> <xs:annotation>
<xs:documentation>ISM company information</xs:documentation> <xs:documentation>ISM company information. Must be provided when GrossTonnage &gt;= 500 or Violation 821 will occur.</xs:documentation>
</xs:annotation> </xs:annotation>
<xs:complexType> <xs:complexType>
<xs:sequence> <xs:sequence>
@ -1279,7 +1300,7 @@
</xs:annotation> </xs:annotation>
<xs:simpleType> <xs:simpleType>
<xs:restriction base="xs:string"> <xs:restriction base="xs:string">
<xs:length value="2" /> <xs:pattern value="[0-9]{2}" />
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
@ -1371,9 +1392,9 @@
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
<xs:element minOccurs="0" name="DeplacementSummerDraught_TNE" type="xs:float"> <xs:element minOccurs="0" name="DeadWeightSummer_TNE" type="xs:float">
<xs:annotation> <xs:annotation>
<xs:documentation>Deplacement (summer draught) in tons (TNE)</xs:documentation> <xs:documentation>Dead weight summer in tons (TNE).</xs:documentation>
</xs:annotation> </xs:annotation>
</xs:element> </xs:element>
</xs:sequence> </xs:sequence>
@ -1523,7 +1544,7 @@
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
<xs:element minOccurs="0" name="DateOfLastExpandedInspection" type="xs:date"> <xs:element name="DateOfLastExpandedInspection" type="xs:date">
<xs:annotation> <xs:annotation>
<xs:documentation>Date of last expanded inspection</xs:documentation> <xs:documentation>Date of last expanded inspection</xs:documentation>
</xs:annotation> </xs:annotation>
@ -1563,7 +1584,7 @@
</xs:element> </xs:element>
<xs:element name="PortOfCallWhereCompleteMDHNotified"> <xs:element name="PortOfCallWhereCompleteMDHNotified">
<xs:annotation> <xs:annotation>
<xs:documentation>PortofCall where the complete information was notified (as UNECE LOCODE)</xs:documentation> <xs:documentation>PortofCall where the complete information was notified (requires the LOCODE of a german seaport, otherwise Violation 768 will occur).</xs:documentation>
</xs:annotation> </xs:annotation>
<xs:simpleType> <xs:simpleType>
<xs:restriction base="xs:string"> <xs:restriction base="xs:string">
@ -2412,7 +2433,7 @@
<xs:simpleType> <xs:simpleType>
<xs:restriction base="xs:string"> <xs:restriction base="xs:string">
<xs:length value="2" /> <xs:length value="2" />
<xs:pattern value=" [A-Z]{2}" /> <xs:pattern value="[A-Z]{2}" />
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
@ -2609,7 +2630,7 @@
<xs:simpleType> <xs:simpleType>
<xs:restriction base="xs:string"> <xs:restriction base="xs:string">
<xs:length value="2" /> <xs:length value="2" />
<xs:pattern value=" [A-Z]{2}" /> <xs:pattern value="[A-Z]{2}" />
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
@ -3103,7 +3124,7 @@
</xs:element> </xs:element>
<xs:element name="StowagePosition"> <xs:element name="StowagePosition">
<xs:annotation> <xs:annotation>
<xs:documentation>Stowage position</xs:documentation> <xs:documentation>Stowage position. In case of a container the position must be given in Bay-Row-Tier notation (BBBRRTT)</xs:documentation>
</xs:annotation> </xs:annotation>
<xs:simpleType> <xs:simpleType>
<xs:restriction base="xs:string"> <xs:restriction base="xs:string">
@ -3145,6 +3166,17 @@
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
<xs:element name="Identifier">
<xs:annotation>
<xs:documentation>Unique identifier. Will be addressed in possible Violations in this dg item.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1" />
<xs:maxLength value="36" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
@ -3280,6 +3312,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
<xs:element name="Identifier">
<xs:annotation>
<xs:documentation>Unique identifier. Will be addressed in possible Violations in this dg item.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1" />
<xs:maxLength value="36" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
@ -3377,6 +3420,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
<xs:element name="Identifier">
<xs:annotation>
<xs:documentation>Unique identifier. Will be addressed in possible Violations in this dg item.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1" />
<xs:maxLength value="36" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
@ -3485,6 +3539,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
<xs:element name="Identifier">
<xs:annotation>
<xs:documentation>Unique identifier. Will be addressed in possible Violations in this dg item.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1" />
<xs:maxLength value="36" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
@ -3583,6 +3648,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
<xs:element name="Identifier">
<xs:annotation>
<xs:documentation>Unique identifier. Will be addressed in possible Violations in this dg item.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1" />
<xs:maxLength value="36" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
@ -3939,7 +4015,7 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:element> </xs:element>
<xs:element name="StowagePosition"> <xs:element name="StowagePosition">
<xs:annotation> <xs:annotation>
<xs:documentation>Stowage position</xs:documentation> <xs:documentation>Stowage position. In case of a container the position must be given in Bay-Row-Tier notation (BBBRRTT)</xs:documentation>
</xs:annotation> </xs:annotation>
<xs:simpleType> <xs:simpleType>
<xs:restriction base="xs:string"> <xs:restriction base="xs:string">
@ -3981,6 +4057,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
<xs:element name="Identifier">
<xs:annotation>
<xs:documentation>Unique identifier. Will be addressed in possible Violations in this dg item.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1" />
<xs:maxLength value="36" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
@ -4116,6 +4203,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
<xs:element name="Identifier">
<xs:annotation>
<xs:documentation>Unique identifier. Will be addressed in possible Violations in this dg item.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1" />
<xs:maxLength value="36" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
@ -4213,6 +4311,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
<xs:element name="Identifier">
<xs:annotation>
<xs:documentation>Unique identifier. Will be addressed in possible Violations in this dg item.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1" />
<xs:maxLength value="36" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
@ -4321,6 +4430,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
<xs:element name="Identifier">
<xs:annotation>
<xs:documentation>Unique identifier. Will be addressed in possible Violations in this dg item.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1" />
<xs:maxLength value="36" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
@ -4419,6 +4539,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
<xs:element name="Identifier">
<xs:annotation>
<xs:documentation>Unique identifier. Will be addressed in possible Violations in this dg item.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1" />
<xs:maxLength value="36" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
@ -4431,46 +4562,46 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:element> </xs:element>
</xs:sequence> </xs:sequence>
</xs:choice> </xs:choice>
<xs:element minOccurs="0" name="Violations"> <xs:element minOccurs="0" name="Violations">
<xs:annotation> <xs:annotation>
<xs:documentation>A list of violations reported by the NSW core system. Declarants do not need to fill this list.</xs:documentation> <xs:documentation>A list of violations reported by the NSW core system. Declarants do not need to fill this list.</xs:documentation>
</xs:annotation> </xs:annotation>
<xs:complexType> <xs:complexType>
<xs:sequence> <xs:sequence>
<xs:element maxOccurs="unbounded" name="Violation"> <xs:element maxOccurs="unbounded" name="Violation">
<xs:annotation> <xs:annotation>
<xs:documentation>Information for each reported violation</xs:documentation> <xs:documentation>Information for each reported violation</xs:documentation>
</xs:annotation> </xs:annotation>
<xs:complexType> <xs:complexType>
<xs:sequence> <xs:sequence>
<xs:element name="ViolationCode"> <xs:element name="ViolationCode">
<xs:annotation> <xs:annotation>
<xs:documentation>NSW violation code</xs:documentation> <xs:documentation>NSW violation code</xs:documentation>
</xs:annotation> </xs:annotation>
<xs:simpleType> <xs:simpleType>
<xs:restriction base="xs:int"> <xs:restriction base="xs:int">
<xs:minInclusive value="100"/> <xs:minInclusive value="100" />
<xs:maxInclusive value="999"/> <xs:maxInclusive value="999" />
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
<xs:element name="ViolationText"> <xs:element name="ViolationText">
<xs:annotation> <xs:annotation>
<xs:documentation>Violation description</xs:documentation> <xs:documentation>Violation description</xs:documentation>
</xs:annotation> </xs:annotation>
<xs:simpleType> <xs:simpleType>
<xs:restriction base="xs:string"> <xs:restriction base="xs:string">
<xs:minLength value="1"/> <xs:minLength value="1" />
<xs:maxLength value="255"/> <xs:maxLength value="255" />
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:element> </xs:element>
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>