Mass Transit with Quartz / Scheduling - Are there any example implementations out there? - scheduling

I have searched high and low for an example implementation or blog post on how to use Mass Transit's Quartz integration (https://github.com/MassTransit/MassTransit-Quartz).
At the moment I have to make do with just looking at the unit tests that come with the code base and I'm not making much progress.
Are there any examples or good blog posts out there to help me get started with Mass Transit and Quartz Scheduling?

This example lets you persist a MassTransit scheuled message in a SQL database. Out of the box, MassTransit only persists in memory without some config changes.
First of all you need a subtle change to your app/web.config file to include the following 2 blocks:
<configSections>
<section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<quartz>
<add key="quartz.scheduler.instanceName" value="MassTransit-Quartz" />
<add key="quartz.scheduler.instanceId" value="AUTO" />
<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
<add key="quartz.threadPool.threadCount" value="4" />
<add key="quartz.threadPool.threadPriority" value="2" />
<add key="quartz.jobStore.misfireThreshold" value="60000" />
<add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz" />
<add key="quartz.jobStore.useProperties" value="false" />
<add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz" />
<add key="quartz.jobStore.clustered" value="true" />
<add key="quartz.jobStore.tablePrefix" value="QRTZ_" />
<add key="quartz.jobStore.dataSource" value="quartzDS" />
<add key="quartz.dataSource.quartzDS.connectionString" value="Server=(local);Database=Quartz;Integrated Security=SSPI" />
<add key="quartz.dataSource.quartzDS.provider" value="SqlServer-20" />
Then, in your local SQL, create a new database named "Quartz", download the quartz.net source and locate the database script
"tables_sqlServer.sql"
run this against your Quartz local database to create the schema.
Now you have everything ready to persist scheduled messages in the database, you need to subscribe these two consumers from the MassTransit Quartz integration library:
var scheduler = CreateScheduler();
sb.SubscribeConsumer(() => new ScheduleMessageConsumer(scheduler));
sb.SubscribeConsumer(() => new CancelScheduledMessageConsumer(scheduler));
Where scheduler is an IScheduler:
static IScheduler CreateScheduler()
{
ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
return schedulerFactory.GetScheduler();
}
and sb is your servicebus of type IServiceBus.
Finally, in your code call:
Bus.ScheduleMessage(SchedulePeriodInSecondsFromNow, MessageToSchedule);
And have a consumer for the "MessageToSchedule" type.
If you open up the database and query the QRTZ_TRIGGERS table, you will see jobs appearing there and in QRTZ_JOB_DETAILS.
Hope this helps!

Related

WCF 4 routing service throws handler error

I am trying to use WCF 4 routing declaratively to redirect one branch of my (REST) web services to an alternate server. I configured WCF's System.ServiceModel.Routing.RoutingService to route http://oldserver:81/FileService/ calls to http://newserver:82/FileService/, but when I try to access the redirected service, all it does is throw the error
Handler "HttpLogging" has a bad module "HttpLoggingModule" in its module list
I can enter URLs to the new service in my browser and they work fine, but URLs to the old service (to be re-routed) fail.
I have added the following routing configuration into my web service application:
<configuration>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<behaviors>
<serviceBehaviors>
<behavior name="routingConfig">
<!-- Specify the routing table to use. -->
<routing filterTableName="routingTable1" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
<!-- WCF routing table -->
<routing>
<filters>
<filter name="FileFilter1" filterType="EndpointName" filterData="FileService"/>
</filters>
<filterTables>
<filterTable name="routingTable1">
<add filterName="FileFilter1" endpointName="FileService" />
</filterTable>
</filterTables>
</routing>
<client>
<!-- Destination endpoint defining the base URL where File messages will be routed. -->
<endpoint name="FileService"
address="http://newserver:82/FileService/"
binding="webHttpBinding"
contract="*" />
</client>
<services>
<!-- WCF routing service. -->
<service name="System.ServiceModel.Routing.RoutingService" behaviorConfiguration="routingConfig" >
<host>
<baseAddresses>
<!-- The service endpoint to be redirected. -->
<add baseAddress="http://oldserver:81/FileService" />
</baseAddresses>
</host>
<!-- Define the endpoints of the service to receive messages. -->
<endpoint name="reqReplyEndpoint" binding="webHttpBinding" contract="System.ServiceModel.Routing.IRequestReplyRouter" address="" />
</service>
</services>
There is no longer a FileService service in the application, except the one that should be exposed by the routing service.
I've tried:
filter types of MatchAll, EndpointAddress, and PrefixEndpointAddress;
various forms of the old service addresses;
different names for filters, routing tables, services;
renaming contracts.
None of it gets my client to call the redirected service, much less even any indication that the routing service is operational or even configured at all.
How do I make the routing actually work? Failing that, how would I debug it so I can determine what to fix?
The general problem I see is that you are trying to route REST calls with Routing Service, which is not supported. MSDN reference:
https://msdn.microsoft.com/en-us/library/ee517423.aspx
The Routing Service does not currently support routing of WCF REST
services. To route REST calls, consider using System.Web.Routing or
Application Request Routing
(http://go.microsoft.com/fwlink/?LinkId=164589).
Blockquote

ad user not able to login even on assiging sitecore\Sitecore Client Users role

I have integrated active directory module with sitecore, I am able to see the users from ad in sitecore user manager. Now i want to verify if the ad user can login to sitecore. I assigned sitecore\Sitecore Client Users role for the user and tried to login as
Username: domain\username
Password: pw
I see a wierd error when login button is hit. Below is the error.
But when i check the set as administrator check box for this user, i am able to login with
Username: domain\username
Password: pw
Any help is appreciated.
Thanks.
Server Error in '/' Application.
Creating an instance of the COM component with CLSID {080D0D78-F421-11D0-A36E-00C04FB950DC} from the IClassFactory failed due to the following error: 800401e4 Invalid syntax (Exception from HRESULT: 0x800401E4 (MK_E_SYNTAX)).
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Runtime.InteropServices.COMException: Creating an instance of the COM component with CLSID {080D0D78-F421-11D0-A36E-00C04FB950DC} from the IClassFactory failed due to the following error: 800401e4 Invalid syntax (Exception from HRESULT: 0x800401E4 (MK_E_SYNTAX)).
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[COMException (0x800401e4): Creating an instance of the COM component with CLSID {080D0D78-F421-11D0-A36E-00C04FB950DC} from the IClassFactory failed due to the following error: 800401e4 Invalid syntax (Exception from HRESULT: 0x800401E4 (MK_E_SYNTAX)).]
System.Web.Security.DirectoryInformation.GetADsPath(String dn) +108
System.Web.DataAccess.ActiveDirectoryConnectionHelper.GetDirectoryEntry(DirectoryInformation directoryInfo, String objectDN, Boolean revertImpersonation) +42
System.Web.Security.ActiveDirectoryMembershipProvider.ValidateUserCore(String username, String password) +1970
System.Web.Security.ActiveDirectoryMembershipProvider.ValidateUser(String username, String password) +39
LightLDAP.SitecoreADMembershipProvider.ValidateUser(String username, String password) +193
Sitecore.Data.DataProviders.NullRetryer.Execute(Func`1 action, Action recover) +394
Sitecore.Security.SitecoreMembershipProvider.ValidateUser(String username, String password) +319
System.Web.UI.WebControls.Login.AuthenticateUsingMembershipProvider(AuthenticateEventArgs e) +105
System.Web.UI.WebControls.Login.AttemptLogin() +160
System.Web.UI.WebControls.Login.OnBubbleEvent(Object source, EventArgs e) +93
System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +84
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3804
I came across similar issue for my one of my web app.
If you are still facing this problem, you can fix this by going to Advanced Settings of the IIS App pool of your application and setting "Load User Profile" option to True.
#MattGartman here are the membership and role poviders
<membership defaultProvider="sitecore" hashAlgorithmType="SHA1">
<providers>
<clear />
<add name="sitecore" type="Sitecore.Security.SitecoreMembershipProvider, Sitecore.Kernel" realProviderName="switcher" providerWildcard="%" raiseEvents="true" />
<add name="sql" type="System.Web.Security.SqlMembershipProvider" connectionStringName="core" applicationName="sitecore" minRequiredPasswordLength="1" minRequiredNonalphanumericCharacters="0" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="256" />
<add name="switcher" type="Sitecore.Security.SwitchingMembershipProvider, Sitecore.Kernel" applicationName="sitecore" mappings="switchingProviders/membership" />
<add name="ad" type="LightLDAP.SitecoreADMembershipProvider" connectionStringName="ADConnString" applicationName="sitecore" minRequiredPasswordLength="1" minRequiredNonalphanumericCharacters="0" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" connectionUsername="domain\username" connectionPassword="pw" connectionProtection="Secure" attributeMapUsername="sAMAccountName" enableSearchMethods="true" customFilter="(memberOf=CN=RegionsComSitecore,OU=Groups,DC=c,DC=pk,DC=com)" />
</providers>
</membership>
<roleManager defaultProvider="sitecore" enabled="true">
<providers>
<clear />
<add name="sitecore" type="Sitecore.Security.SitecoreRoleProvider, Sitecore.Kernel" realProviderName="switcher" raiseEvents="true" />
<add name="sql" type="System.Web.Security.SqlRoleProvider" connectionStringName="core" applicationName="sitecore" />
<add name="switcher" type="Sitecore.Security.SwitchingRoleProvider, Sitecore.Kernel" applicationName="sitecore" mappings="switchingProviders/roleManager" />
<add name="ad" type="LightLDAP.SitecoreADRoleProvider" connectionStringName="ADConnString" applicationName="sitecore" username=" domain\username" password="pw" attributeMapUsername="sAMAccountName" cacheSize="2MB" customFilter="(memberOf=CN=RegionsComSitecore,OU=Groups,DC=c,DC=pk,DC=com)" />
</providers>
</roleManager>
here is the ldap.config
<pipelines>
<initializeAdUserEntry>
<!--
Use the processor if all new user should have a predefiled value in a property.
The PropertyName parameter defines the name of the property.
The DefaultValue parameter defines the default value of the property.
-->
<!--
<processor type="LightLDAP.Pipelines.InitializeAdEntry.SetPropertyValue, LightLDAP">
<PropertyName desc="AD property name ">type the property name here</PropertyName>
<DefaultValue desc="AD property name ">type the default property value here</DefaultValue>
</processor>
-->
<!--
Use the processor if all new roles should be a member of the predefined role.
The RoleName parameter defines the name of the main role.
-->
<!--
<processor type="LightLDAP.Pipelines.InitializeAdEntry.AddToRole, LightLDAP">
<RoleName desc="AD group">type role name here</RoleName>
</processor>
-->
<processor type="LightLDAP.Pipelines.InitializeAdEntry.CommitChanges, LightLDAP"/>
</initializeAdUserEntry>
<initializeAdRoleEntry>
<!--
Use the processor if all new user should have a predefiled value in a property.
The PropertyName parameter defines the name of the property.
The DefaultValue parameter defines the default value of the property.
-->
<!--
<processor type="LightLDAP.Pipelines.InitializeAdEntry.SetPropertyValue, LightLDAP">
<PropertyName desc="AD property name ">type the property name here</PropertyName>
<DefaultValue desc="AD property value ">type the default property value here</DefaultValue>
</processor>
-->
<!--
Use the processor if all new roles should be a member of the predefined role.
The RoleName parameter defines the name of the main role.
-->
<!--
<processor type="LightLDAP.Pipelines.InitializeAdEntry.AddToRole, LightLDAP">
<RoleName desc="AD group">type role name here</RoleName>
</processor>
-->
<processor type="LightLDAP.Pipelines.InitializeAdEntry.CommitChanges, LightLDAP"/>
</initializeAdRoleEntry>
</pipelines>
<settings>
<!-- Defines the logging level of the module. If true, dumps every action entry into the log.
Default is false
-->
<setting name="LDAP.Debug" value="true" />
<!-- Defines if the configuration assumes indirect membership on common operations.
This setting affects the membership verification during login and user access check.
Default is false
-->
<setting name="LDAP.IncludeIndirectMembership" value="false" />
<!-- Defines if a certain profile should be applied for each user by default.
If the setting is not specified or is empty, no particular profile item is used.
Default is ""
-->
<!-- ENABLE SORT OPERATION
Determines whether the sorting is enabled
-->
<setting name="LDAP.EnableSorting" value="false" />
<!-- Default Sort Key-->
<setting name="LDAP.SortKey" value="codePage" />
<!-- LDAP GET ALL USERS SIZE LIMIT
Determines the max number of returned users for GetAll method
-->
<setting name="LDAP.SizeLimit" value="1000" />
<!-- LDAP FIND USERS SIZE LIMIT
Determines the max number of returned users for GetAll method
-->
<setting name="LDAP.FindSizeLimit" value="100" />
<!-- LDAP USER CACHE SIZE
Determines the size of the ldap users cache.
Specify the value in bytes or append the value with KB, MB or GB
A value of 0 (zero) disables the cache.
-->
<setting name="LDAP.Caching.UserCache" value="2MB" />
<!-- LDAP MEMBEROF CACHE SIZE
Determines the size of the ldap users cache.
Specify the value in bytes or append the value with KB, MB or GB
A value of 0 (zero) disables the cache.
-->
<setting name="LDAP.Caching.MemberOfCache" value="2MB" />
<!-- LDAP MEMBERS CACHE SIZE
Determines the size of the ldap users cache.
Specify the value in bytes or append the value with KB, MB or GB
A value of 0 (zero) disables the cache.
-->
<setting name="LDAP.Caching.MembersCache" value="2MB" />
<!-- SETTINGS PROPERTY VALUE FACTORY
Returns an SettingsPropertyValueFactory interface that resolves the active directory properties.
-->
<setting name="LDAP.SettingsPropertyValueFactory" value="LightLDAP.SettingsPropertyValueFactory, LightLDAP" />
<!-- RECONNECT PERIOD
Determines a reconnect period for attempts to restore connection after the connection gets break.
-->
<setting name="LDAP.ReconnectPeriod" value="0.00:00:10" />
<!-- TIME OUT NOTIFICATION
Determines a timeout for notification.
-->
<setting name="LDAP.NotificationTimeOut" value="1.00:00:00" />
<!-- FULL NAME PROPERTY NAME
Determines the full name property mapping.
-->
<setting name="LDAP.FullName" value="ad|unicode string|displayName" />
<!-- DELETE USER SCOPE
Determines the scope of the "delete user" operation.
-->
<setting name="LDAP.DeleteScope" value="Subtree" />
<!-- MAX VALUE RANGE
Determines the maximal value of an AD range attribute.
-->
<setting name="LDAP.MaxValueRange" value="1500" />
</settings>
For AD Enabled login, try login from /sitecore/admin/ldaplogin.aspx page.
I know this question is old, but I've had this issue recently and spent quite a bit of time researching the cause and solution via Microsoft docs, etc. There is sometimes an issue caused by the IIS refresh process when trying to access certain interfaces within com objects that are dynamically loaded from various DLL written in C++. These kind of DLLs/interfaces can be tricky and confusing. I have found that the best solution is to avoid some calls to the User Group principal objects that are given by this interface. If you are calling a method that looks something like: [Some user object].IsMemberOf([Some group object]). Try changing the code to avoid calling any function on the user object. From the example above, you could change the code to look like this:
foreach (var user in [Some group object].GetUsers())
{
if (user.SamAccountName == [Some user object].SamAccountName)
{
// Do your work here
}
}
Of course, the operations that you are performing in your code may not be the same as my example above, but hopefully that gives a basic understanding of the type of operations you may need to avoid.

Way to nest multiple voice triggers when launching an app with GDK

Is there a way to nest voice triggers when launching an app on Google Glass using the GDK? For example instead of just saying "ok, glass" -> "What's its power level?" I'd like to have the app present an option. For example "ok, glass" -> "What's its power level?" -> "Over 9000" OR "Under 9000". Any help would be great!
If you have multiple activities/services installed on Glass that have the same voice trigger intent filter, all of their names (based on the android:label attribute of the <activity> or <service> tag in AndroidManifest.xml) will appear in a disambiguation "submenu" when you speak that voice trigger.
For example (assume that res/xml/play_a_game_trigger.xml represents a voice trigger for the string "play a game"):
<activity android:label="Tennis">
<intent-filter>
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
</intent-filter>
<meta-data android:name="com.google.android.glass.VoiceTrigger"
android:resource="#xml/play_a_game_trigger" />
</activity>
<activity android:label="Bowling">
<intent-filter>
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
</intent-filter>
<meta-data android:name="com.google.android.glass.VoiceTrigger"
android:resource="#xml/play_a_game_trigger" />
</activity>
would give you a voice menu flow that looks like
ok glass → play a game → Tennis
Bowling
Do note, however, that this menu would also include activities/services from other APKs that use the same voice trigger as well.
You can find more details at the Voice Input page of the GDK documentation.
The proper way to do this is using an input tag inside the trigger
<trigger keyword="#string/start_app" >
<input prompt="#string/promt_text" />
</trigger>
This prompts an input and waits for more audio speech.
Then in your activity you can capture this text with:
ArrayList<String> text = getIntent().getExtras().getStringArrayList(RecognizerIntent.EXTRA_RESULTS);

Integrating Simplemembership in an existing webapplication painlessly

Could someone please elaborate on how to implement simplemembership into an existing web application. All the blogs are very confusing and lack detail. There's one that I found that doesn't appear to work. I have an existing blog app that I've build and I'm looking for a painless way to use simplemembership..
Please help..
Thanks
If you are using MVC4, as you mentioned in tags:
1) Create new MVC4 Internet WebApplication
2) Copy from it:
a)AccountController from Controllers folder
b)AccountModels from Models folder
c)Account folder from View folder
4) Past it to your application
5)Change everythere namesoaces to your application
6)Modify web.config:
Add (you may copy it from new application):
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
<membership>
<providers>
<clear />
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="gunselEntities" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="3" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
</system.web>
7) Add Aspnet membership tables to your database. Navigate to the wizard(C:\Windows\Microsoft.NET\Framework[framework version]\aspnet_regsql) and launch it. It will run special wizzard, which helps to add tables.

Server did not recognize the value of HTTP Header SOAP

Here you can find the WSDL for my Jobs.asmx webService. http://recpushdata.cyndigo.com/jobs.asmx
The Thing is I have created a HTML page at http://bugmusic.cyndigo.com/CallWebService.html
and its returning an Error Server did not recognize the value of HTTP Header SOAP.
I am not able to find the bug.
add or remove the httppost, httpget protocols. like below:
in your Web.config
<webServices><br>
<protocols><br>
<add name="HttpPost"/> <br>
<add name="HttpGet"/> <br>
</protocols><br>
</webServices><br>
in your machine.config:<br>
<system.web><br>
...<br>
<webServices><br>
<protocols><br>
<add name="HttpSoap"/><br>
<add name="HttpPost"/><br>
<add name="HttpGet"/><br>
<add name="Documentation"/><br>
<add name="HttpPostLocalhost"/><br>
</protocols><br>
</webServices><br>
...<br>
</system.web<br>