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>
<SendNSWMessageService.Properties.Settings>
<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>
</SendNSWMessageService.Properties.Settings>
</applicationSettings>

View File

@ -48,10 +48,10 @@ namespace SendNSWMessageService
public void Init(string[] args)
{
this._timer = new Timer();
this._timer.Interval = 5000; // 5 sec
this._timer.Interval = 60000; // 1 min
this._timer.Elapsed += _timer_Elapsed;
this._timer.Enabled = true;
_timer_Elapsed(null, null);
}
void _timer_Elapsed(object sender, ElapsedEventArgs e)
@ -67,21 +67,21 @@ namespace SendNSWMessageService
// 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
{
_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;
// switch über passendes HIS / Schnittstelle
switch (message.MessageCore.InitialHIS)
switch (entity.MessageCore.InitialHIS)
{
case Message.NSWProvider.DBH:
sendSucceeded = bsmd.dbh.Request.SendMessage(message);
sendSucceeded = bsmd.dbh.Request.SendMessage(entity);
break;
case Message.NSWProvider.DAKOSY:
_log.Warn("Cannot send via DAKOSY yet");
@ -91,20 +91,20 @@ namespace SendNSWMessageService
_log.Warn("Cannot send via Daten und Dienste HRO yet");
break;
default:
_log.WarnFormat("Initial HIS not specified for message {0}", message.Id);
_log.WarnFormat("Initial HIS not specified for message {0}", entity.Id);
break;
}
if (sendSucceeded)
{
message.InternalStatus = Message.BSMDStatus.SENT;
DBManager.Instance.Save(message);
entity.InternalStatus = Message.BSMDStatus.SENT;
DBManager.Instance.Save(entity);
}
}
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;
}
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();
SqlCommand cmd = new SqlCommand();
@ -88,11 +103,12 @@ namespace bsmd.database
SqlDataReader reader = this.PerformCommand(cmd);
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;
}
@ -112,32 +128,44 @@ namespace bsmd.database
return result;
}
public void Save(Message message)
public void Save(DatabaseEntity entity)
{
SqlCommand cmd = new SqlCommand();
message.PrepareSave(cmd);
entity.PrepareSave(cmd);
int queryResult = this.PerformNonQuery(cmd);
switch(queryResult)
{
case 1:
_log.InfoFormat("Message {0} saved", message.Id); break;
_log.InfoFormat("Message {0} saved", entity.Id); break;
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:
_log.WarnFormat("Message {0} save: error occurred", message.Id); break;
_log.WarnFormat("Message {0} save: error occurred", entity.Id); break;
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
#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, ReportingParty> reportingPartyDict = this.GetReportingPartyDict();
List<DatabaseEntity> result = new List<DatabaseEntity>();
// Zuordnung MessageCore,Zuordnung Reporting party
Message.AssignReportingParties(messageList, reportingPartyDict);
@ -159,15 +187,17 @@ namespace bsmd.database
List<DatabaseEntity> statList = msgClass.LoadList(reader);
if (statList.Count > 0) message.DerivedMessage = statList[0];
((IMessageClass)msgClass).MessageHeader = message;
this.LoadDependingLists(msgClass);
result.Add(msgClass);
}
else
{
_log.ErrorFormat("cannot create a message class for notification type {0}", message.MessageNotificationClass);
result.Add(message);
}
}
this.LoadDependingLists(message);
}
return result;
}
#region CreateMessage()
@ -206,9 +236,10 @@ namespace bsmd.database
case Message.NotificationClass.HAZA:
case Message.NotificationClass.HAZD:
default:
_log.WarnFormat("CreateMessage: message type {0} is not supported", notificationClass.ToString());
break;
default:
break; // VISIT, TRANSIT
}
return result;
}

View File

@ -18,9 +18,23 @@ namespace bsmd.database
public abstract class DatabaseEntity
{
protected Guid? id;
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>
/// SQL Table name to construct queries
/// </summary>

View File

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

View File

@ -15,7 +15,6 @@ namespace bsmd.database
{
private Guid messageHeaderId;
private Guid? messageCoreId;
private MessageCore messageCore;
private Guid? reportingPartyId;
private ReportingParty reportingParty;
private DateTime? created;
@ -52,7 +51,8 @@ namespace bsmd.database
WAS_ID,
WDSP_ID,
BPOL_ID,
SEC_ID
SEC_ID,
HERBERG_FORMGUID
}
/// <summary>
@ -95,11 +95,6 @@ namespace bsmd.database
/// </summary>
public string ClientRequestId { set; get; }
/// <summary>
/// Referenz zur eigentlichen Schiffankunft
/// </summary>
public MessageCore MessageCore { get { return this.messageCore; } }
public Guid? MessageId { get; set; }
public DateTime? SentAt { get; set; }
@ -116,21 +111,11 @@ namespace bsmd.database
public DateTime? Created { get { return this.created; } }
/// <summary>
/// Nachrichtentyp der abgeleiteten Meldeklassen
/// </summary>
public NotificationClass MessageNotificationClass { get; set; }
/// <summary>
/// Der Meldende
/// </summary>
public ReportingParty ReportingParty { get { return this.reportingParty; } }
/// <summary>
/// Status für Services
/// </summary>
public BSMDStatus InternalStatus { get; set; }
/// <summary>
/// die zur Kommunikation zu verwendende HIS Schnittstelle
/// </summary>
@ -280,7 +265,7 @@ namespace bsmd.database
foreach (Message message in messages)
{
if (message.messageCoreId.HasValue && messageCores.ContainsKey(message.messageCoreId.Value))
message.messageCore = messageCores[message.messageCoreId.Value];
message.MessageCore = messageCores[message.messageCoreId.Value];
}
}

View File

@ -43,6 +43,10 @@ namespace bsmd.database
public Message.NSWProvider InitialHIS { get; set; }
public Guid? HerbergFormGuid { get; set; }
public Guid? HerbergFormTemplateGuid { get; set; }
#endregion
public override void PrepareSave(IDbCommand cmd)
@ -74,12 +78,16 @@ namespace bsmd.database
else scmd.Parameters.AddWithValue("@P12", DBNull.Value);
scmd.Parameters.AddWithValue("@P13", this.BSMDStatus);
scmd.Parameters.AddWithValue("@P14", this.InitialHIS);
scmd.Parameters.AddWithNullableValue("@P15", this.HerbergFormGuid);
scmd.Parameters.AddWithNullableValue("@P16", this.HerbergFormTemplateGuid);
if (this.IsNew)
{
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 " +
"(@P1, @P2, @P3, @P4, @P5, @P6, @P7, @P8, @P9, @P10, @P11, @P12, @P13, @P14)", this.Tablename);
"Previous, Next, IsTransit, Wetris_zz_56_datensatz_id, BSMDStatus, InitialHIS, HerbergFormGuid, " +
"HerbergFormTemplateGuid) VALUES " +
"(@P1, @P2, @P3, @P4, @P5, @P6, @P7, @P8, @P9, @P10, @P11, @P12, @P13, @P14, @P15, @P16)",
this.Tablename);
scmd.CommandText = query;
}
else
@ -87,7 +95,8 @@ namespace bsmd.database
scmd.Parameters.AddWithValue("@ID", this.Id);
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, " +
"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)
{
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);
switch (filter)
@ -103,7 +113,13 @@ namespace bsmd.database
case Message.LoadFilter.WETRIS_SHIP_ID:
{
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;
}
case Message.LoadFilter.ALL:
@ -135,6 +151,8 @@ namespace bsmd.database
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.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);
}

View File

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

View File

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

View File

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

View File

@ -12,38 +12,19 @@ namespace bsmd.dbh.ResponseService
[ServiceContract]
public interface IResponseService
{
/*
[OperationContract]
string GetData(int value);
*/
/// <summary>
/// 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.
/// </summary>
[OperationContract]
[XmlSerializerFormatAttribute()]
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
// associated with an assembly.
[assembly: AssemblyTitle("bsmd.dbh.ResponseService")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("bsmd.dbh.ResponseService")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyDescription("Webservice zum Empfang der NSW Response Nachrichten von dbh")]
[assembly: AssemblyCulture("")]
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
// 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.
@ -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
[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 System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using log4net;
using log4net;
namespace bsmd.dbh.ResponseService
{
@ -15,16 +8,10 @@ namespace bsmd.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)
{
_log.Info("response received!");
Response.ProcessResponse(root);
}
Response.ProcessResponse(root, Properties.Settings.Default.DBConnectionString);
}
}
}

View File

@ -1,6 +1,11 @@
<?xml version="1.0"?>
<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>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
@ -32,5 +37,11 @@
-->
<directoryBrowse enabled="true"/>
</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>

View File

@ -63,9 +63,25 @@
</ItemGroup>
<ItemGroup>
<Content Include="ResponseService.svc" />
<Content Include="Web.config" />
<Content Include="Web.config">
<SubType>Designer</SubType>
</Content>
</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">
<DependentUpon>ResponseService.svc</DependentUpon>
</Compile>
@ -77,6 +93,17 @@
</ItemGroup>
<ItemGroup>
<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">
<DependentUpon>Web.config</DependentUpon>
</None>
@ -98,6 +125,12 @@
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>..\bsmdKey.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<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.
//
namespace bsmd.dbh.response
{

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.Collections.Generic;
using log4net;
using bsmd.database;
using bsmd.dbh.request;
//using bsmd.dbh.request;
using bsmd.dbh.DBHWebReference;
namespace bsmd.dbh
{
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
Root root = new Root();
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;
Dbh_Osis_Answ_Ws client = new Dbh_Osis_Answ_Ws();
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;
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:
{
root.Type = RootType.VISIT;
root.Item = new RootVisit();
RootVisit rootVisit = new RootVisit();
rootType = RootType.VISIT;
if (aMessage.MessageCore.IMO != null)
{
((RootVisit)root.Item).ItemElementName = ItemChoiceType.IMONumber;
((RootVisit)root.Item).Item = aMessage.MessageCore.IMO;
rootVisit.ItemElementName = ItemChoiceType.IMONumber;
rootVisit.Item = aMessage.MessageCore.IMO;
}
else
{
((RootVisit)root.Item).ItemElementName = ItemChoiceType.ENINumber;
((RootVisit)root.Item).Item = aMessage.MessageCore.ENI;
rootVisit.ItemElementName = ItemChoiceType.ENINumber;
rootVisit.Item = aMessage.MessageCore.ENI;
}
((RootVisit)root.Item).PortOfCall = aMessage.MessageCore.PoC;
((RootVisit)root.Item).ETAPortOfCall = aMessage.MessageCore.ETA.Value;
rootVisit.PortOfCall = aMessage.MessageCore.PoC;
rootVisit.ETAPortOfCall = aMessage.MessageCore.ETA.Value;
item = rootVisit;
break;
}
#endregion
#region TRANSIT
case Message.NotificationClass.TRANSIT:
root.Type = RootType.TRANSIT;
root.Item = new RootTransit();
{
RootTransit rootTransit = new RootTransit();
rootType = RootType.TRANSIT;
if (aMessage.MessageCore.IMO != null)
{
((RootTransit)root.Item).ItemElementName = ItemChoiceType1.IMONumber;
((RootTransit)root.Item).Item = aMessage.MessageCore.IMO;
rootTransit.ItemElementName = ItemChoiceType1.IMONumber;
rootTransit.Item = aMessage.MessageCore.IMO;
}
else
{
((RootTransit)root.Item).ItemElementName = ItemChoiceType1.ENINumber;
((RootTransit)root.Item).Item = aMessage.MessageCore.ENI;
rootTransit.ItemElementName = ItemChoiceType1.ENINumber;
rootTransit.Item = aMessage.MessageCore.ENI;
}
((RootTransit)root.Item).ETAKielCanal = aMessage.MessageCore.ETA.Value;
rootTransit.ETAKielCanal = aMessage.MessageCore.ETA.Value;
item = rootTransit;
break;
}
#endregion
case Message.NotificationClass.STAT:
#region NOA_NOD
case Message.NotificationClass.NOA_NOD:
{
NOA_NOD noa_nod = dbEntity as NOA_NOD;
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
#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
#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
#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;
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:
throw new NotImplementedException("sending message type not implemented yet!");
{
_log.ErrorFormat("DBH send message: message type {0} not implemented", aMessage.MessageNotificationClass);
break;
}
}
// send object
string result = client.Root(version, timestamp, Properties.Settings.Default.Sender, senderReference, rootType,
item, itemChoiceType2, null, rp, null, null);
return false;
}

View File

@ -10,14 +10,49 @@
using System;
using System.Collections.Generic;
using bsmd.database;
using log4net;
namespace bsmd.dbh
{
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);
if (DBManager.Instance.Connect(connectionString))
{
// Status zu den jeweiligen Nachrichten. Bei uns sollte die Anzahl hier immer 1 sein, da wir die Dinger
// 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.RootMessageType.VIOLATION:
break;
case dbh.response.RootMessageType.WARNING:
case dbh.response.RootMessageType.INFO:
default:
break;
}
}
switch (response.Type)
{
@ -37,7 +72,12 @@ namespace bsmd.dbh
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 Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.EnterpriseServices" />
<Reference Include="System.Web.Services" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@ -60,8 +62,18 @@
<Compile Include="NSWRequest.cs" />
<Compile Include="NSWResponse.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="Response.cs" />
<Compile Include="Web References\DBHWebReference\Reference.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Reference.map</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\bsmd.database\bsmd.database.csproj">
@ -71,7 +83,45 @@
</ItemGroup>
<ItemGroup>
<None Include="..\bsmdKey.snk" />
<None Include="app.config" />
<None Include="NSWResponse.xsd">
<SubType>Designer</SubType>
</None>
<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>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- 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">
<value>https://www.fleettracker.de/api/1.0/WSAPIFormData.php</value>
</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>
</userSettings>
<system.serviceModel>

View File

@ -43,6 +43,10 @@ namespace bsmd.herberg.FormService
this.EventLog.WriteEntry("NSW Send Service started.", EventLogEntryType.Information);
}
protected override void OnStop()
{
}
public void Init(string[] args)
{
this._timer = new Timer();
@ -52,10 +56,6 @@ namespace bsmd.herberg.FormService
}
protected override void OnStop()
{
}
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
lock (this._timerlock)
@ -78,13 +78,16 @@ namespace bsmd.herberg.FormService
body.apiIdentifier = new APIIdentifier();
// von Jan am 1.4.15: (April, April..)
body.apiIdentifier.companyGuid = "f2747e67-0043-43e4-b6a9-1ed3bf9265e4";
body.apiIdentifier.clientGuid = "76994eae-48de-44d4-a86d-6508e2e03dcf";
body.apiIdentifier.companyGuid = Properties.Settings.Default.CompanyGuid.ToString();
body.apiIdentifier.clientGuid = Properties.Settings.Default.ClientGuid.ToString();
body.ffFolderTemplateTypeTag = "NSWAP";
body.ffFolderTemplateTypeTag = "NSWAD";
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.endDate = DateTime.Now + new TimeSpan(30, 0, 0, 0);
body.timeFrameRequestFilter.endDateSpecified = true;
// Liste der verfügbaren Formulare abholen
GetFormDataInfoListResponseData listReponse = client.GetFormDataInfoList(body);
@ -102,8 +105,8 @@ namespace bsmd.herberg.FormService
// Formular abholen
GetFormDataRequestData formBody = new GetFormDataRequestData();
formBody.apiIdentifier = new APIIdentifier();
formBody.apiIdentifier.companyGuid = Guid.NewGuid().ToString(); // TODO
formBody.apiIdentifier.clientGuid = Guid.NewGuid().ToString(); // TODO
formBody.apiIdentifier.companyGuid = Properties.Settings.Default.CompanyGuid.ToString();
formBody.apiIdentifier.clientGuid = Properties.Settings.Default.ClientGuid.ToString();
formBody.formGuid = dataSet.formGuid;
@ -111,6 +114,24 @@ namespace bsmd.herberg.FormService
if (formResponse.success)
{
// 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

View File

@ -56,5 +56,29 @@ namespace bsmd.herberg.FormService.Properties {
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">
<Value Profile="(Default)">http://www.fleettracker.de/api/1.0/WSAPIFormData.php</Value>
</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>
</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>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="Util.cs" />
<Compile Include="Web References\WebReference\Reference.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>

View File

@ -23,6 +23,27 @@
<xs:documentation>Timestamp, when the message is sent</xs:documentation>
</xs:annotation>
</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:annotation>
<xs:documentation>The message type:
@ -355,7 +376,7 @@
<xs:documentation>1 - 999</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:restriction base="xs:int">
<xs:minInclusive value="1" />
<xs:maxInclusive value="999" />
</xs:restriction>
@ -474,7 +495,7 @@
</xs:element>
<xs:element name="PortOfCallWhereCompleteSECNotified">
<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:simpleType>
<xs:restriction base="xs:string">
@ -651,13 +672,13 @@
</xs:element>
<xs:element maxOccurs="10" name="LastTenPortFacilitiesCalled">
<xs:annotation>
<xs:documentation>Last 10 port facilities called</xs:documentation>
<xs:documentation>Last 10 port facilities called.</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="PortFacilityPortName">
<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:simpleType>
<xs:restriction base="xs:string">
@ -668,7 +689,7 @@
</xs:element>
<xs:element minOccurs="0" name="PortFacilityPortCountry">
<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:simpleType>
<xs:restriction base="xs:string">
@ -677,9 +698,9 @@
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="PortFacilityPortLoCode">
<xs:element minOccurs="0" name="PortFacilityPortLoCode">
<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:simpleType>
<xs:restriction base="xs:string">
@ -1173,9 +1194,9 @@
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="ISMCompany">
<xs:element minOccurs="0" name="ISMCompany">
<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:complexType>
<xs:sequence>
@ -1279,7 +1300,7 @@
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:length value="2" />
<xs:pattern value="[0-9]{2}" />
</xs:restriction>
</xs:simpleType>
</xs:element>
@ -1371,9 +1392,9 @@
</xs:restriction>
</xs:simpleType>
</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:documentation>Deplacement (summer draught) in tons (TNE)</xs:documentation>
<xs:documentation>Dead weight summer in tons (TNE).</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
@ -1523,7 +1544,7 @@
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element minOccurs="0" name="DateOfLastExpandedInspection" type="xs:date">
<xs:element name="DateOfLastExpandedInspection" type="xs:date">
<xs:annotation>
<xs:documentation>Date of last expanded inspection</xs:documentation>
</xs:annotation>
@ -1563,7 +1584,7 @@
</xs:element>
<xs:element name="PortOfCallWhereCompleteMDHNotified">
<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:simpleType>
<xs:restriction base="xs:string">
@ -3103,7 +3124,7 @@
</xs:element>
<xs:element name="StowagePosition">
<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:simpleType>
<xs:restriction base="xs:string">
@ -3145,6 +3166,17 @@
</xs:restriction>
</xs:simpleType>
</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:complexType>
</xs:element>
@ -3280,6 +3312,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction>
</xs:simpleType>
</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:complexType>
</xs:element>
@ -3377,6 +3420,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction>
</xs:simpleType>
</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:complexType>
</xs:element>
@ -3485,6 +3539,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction>
</xs:simpleType>
</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:complexType>
</xs:element>
@ -3583,6 +3648,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction>
</xs:simpleType>
</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:complexType>
</xs:element>
@ -3939,7 +4015,7 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:element>
<xs:element name="StowagePosition">
<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:simpleType>
<xs:restriction base="xs:string">
@ -3981,6 +4057,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction>
</xs:simpleType>
</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:complexType>
</xs:element>
@ -4116,6 +4203,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction>
</xs:simpleType>
</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:complexType>
</xs:element>
@ -4213,6 +4311,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction>
</xs:simpleType>
</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:complexType>
</xs:element>
@ -4321,6 +4430,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction>
</xs:simpleType>
</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:complexType>
</xs:element>
@ -4419,6 +4539,17 @@ IMO RESOLUTION MEPC.119(52)</xs:documentation>
</xs:restriction>
</xs:simpleType>
</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:complexType>
</xs:element>