I am using IdentityServer4 and I keep having an issue when the access token has expired. If the user tries to do something like logout after this happens then it gives the error below. But this also happens when you try to login again as well. The only way to fix it is to clear cache and cookies from the browser. I understand the error message but I cant find out where to make the checks for the null because I think the UserClaimsFactory.cs is a protected resource in the nuget package so there is nothing I can do.
System.ArgumentNullException: Value cannot be null.
Parameter name: value
at System.Security.Claims.Claim..ctor(String type, String value, String valueType, String issuer, String originalIssuer, ClaimsIdentity subject, String propertyKey, String propertyValue)
at System.Security.Claims.Claim..ctor(String type, String value)
at Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory`1.<GenerateClaimsAsync>d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory`2.<GenerateClaimsAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory`1.<CreateAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityServer4.AspNetIdentity.UserClaimsFactory`1.<CreateAsync>d__3.MoveNext() in C:\local\identity\server4\AspNetIdentity\src\IdentityServer4.AspNetIdentity\UserClaimsFactory.cs:line 28
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNetCore.Identity.SignInManager`1.<CreateUserPrincipalAsync>d__25.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNetCore.Identity.SecurityStampValidator`1.<ValidateAsync>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler.<HandleAuthenticateAsync>d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.<AuthenticateAsync>d__47.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNetCore.Authentication.AuthenticationService.<AuthenticateAsync>d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.<Invoke>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.<Invoke>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at IdentityServer4.Hosting.BaseUrlMiddleware.<Invoke>d__3.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Hosting\BaseUrlMiddleware.cs:line 36
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()
This is my configuration....
public void ConfigureServices(IServiceCollection services)
{
services.Configure<IISOptions>(iis =>
{
iis.AuthenticationDisplayName = "Windows";
iis.AutomaticAuthentication = false;
});
services.AddDbContext<UserIdentityDbContext>(builder =>
builder.UseSqlServer(Configuration.GetConnectionString("IDPDatabaseConnection"), a => a.MigrationsAssembly("SMI.IDP")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<UserIdentityDbContext>()
.AddDefaultTokenProviders();
services.AddSingleton(typeof(ILocalActiveDirectoryService), typeof(AmericasActiveDirectoryService));
services.AddSingleton(typeof(IIdentityServerUserStore<ApplicationUser>), typeof(UsersRepository));
services.AddScoped<ClaimsService>();
services.AddScoped<UsersRepository>();
services.AddMvc();
var idsrvBuilder = services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(Configuration.GetConnectionString("IDPDatabaseConnection"),
sql => sql.MigrationsAssembly(_migrationsAssembly));
})
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(Configuration.GetConnectionString("IDPDatabaseConnection"),
sql => sql.MigrationsAssembly(_migrationsAssembly));
// this enables automatic token cleanup. this is optional.
options.EnableTokenCleanup = true;
options.TokenCleanupInterval = 30;
})
.AddAspNetIdentity<ApplicationUser>();
idsrvBuilder.AddResourceOwnerValidator<ResourceOwnerPasswordValidator>();
idsrvBuilder.AddProfileService<ProfileService>();
}
After thorough investigation of this event, I've found out the UserClaimsPrincipalFactory is the cause of the issue here:
You will have to override the GetUserIdAsync of your own UserManager in order to make the default factory functions to work properly.
Here's a sample class for you to kick it off with.
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Security.Principal;
using System.Threading.Tasks;
using IdentityModel;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Nozomi.Base.Identity.Models.Identity;
using Nozomi.Service.Identity.Managers;
namespace Nozomi.Service.Identity.Factories
{
public class NozomiUserClaimsPrincipalFactory: UserClaimsPrincipalFactory<User, Role>
{
public new NozomiUserManager UserManager;
public new RoleManager<Role> RoleManager;
public NozomiUserClaimsPrincipalFactory(NozomiUserManager userManager, RoleManager<Role> roleManager,
IOptions<IdentityOptions> options) : base(userManager, roleManager, options)
{
UserManager = userManager;
RoleManager = roleManager;
}
/// <summary>
/// Creates a <see cref="T:System.Security.Claims.ClaimsPrincipal" /> from an user asynchronously.
/// </summary>
/// <param name="user">The user to create a <see cref="T:System.Security.Claims.ClaimsPrincipal" /> from.</param>
/// <returns>The <see cref="T:System.Threading.Tasks.Task" /> that represents the asynchronous creation
/// operation, containing the created <see cref="T:System.Security.Claims.ClaimsPrincipal" />.</returns>
public override async Task<ClaimsPrincipal> CreateAsync(User user)
{
var principal = await base.CreateAsync(user);
var identity = (ClaimsIdentity)principal.Identity;
var claims = new List<Claim>
{
new Claim(JwtClaimTypes.Role, "user")
};
identity.AddClaims(claims);
return principal;
}
/// <summary>Generate the claims for a user.</summary>
/// <param name="user">The user to create a <see cref="T:System.Security.Claims.ClaimsIdentity" /> from.</param>
/// <returns>The <see cref="T:System.Threading.Tasks.Task" /> that represents the asynchronous creation operation, containing the created <see cref="T:System.Security.Claims.ClaimsIdentity" />.</returns>
protected override async Task<ClaimsIdentity> GenerateClaimsAsync(User user)
{
try
{
var userId = await UserManager.GetUserIdAsync(user);
var userNameAsync = await UserManager.GetUserNameAsync(user);
var id = new ClaimsIdentity("Identity.Application",
this.Options.ClaimsIdentity.UserNameClaimType, this.Options.ClaimsIdentity.RoleClaimType);
id.AddClaim(new Claim(this.Options.ClaimsIdentity.UserIdClaimType, userId));
id.AddClaim(new Claim(this.Options.ClaimsIdentity.UserNameClaimType, userNameAsync));
ClaimsIdentity claimsIdentity;
if (this.UserManager.SupportsUserSecurityStamp)
{
claimsIdentity = id;
string type = this.Options.ClaimsIdentity.SecurityStampClaimType;
claimsIdentity.AddClaim(new Claim(type, await this.UserManager.GetSecurityStampAsync(user)));
claimsIdentity = (ClaimsIdentity) null;
type = (string) null;
}
if (this.UserManager.SupportsUserClaim)
{
claimsIdentity = id;
claimsIdentity.AddClaims((IEnumerable<Claim>) await this.UserManager.GetClaimsAsync(user));
claimsIdentity = (ClaimsIdentity) null;
}
return id;
}
catch (Exception ex)
{
Console.WriteLine(ex);
return new ClaimsIdentity();
}
}
}
}
Make sure to symlink your custom objects in the constructor else it won't work.
Within your UserStore class:
/// <summary>
/// Gets the user identifier for the specified <paramref name="user" />.
/// </summary>
/// <param name="user">The user whose identifier should be retrieved.</param>
/// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken" /> used to propagate notifications that the operation should be canceled.</param>
/// <returns>The <see cref="T:System.Threading.Tasks.Task" /> that represents the asynchronous operation, containing the identifier for the specified <paramref name="user" />.</returns>
public override Task<string> GetUserIdAsync(User user, CancellationToken cancellationToken)
{
try
{
if (cancellationToken != null)
cancellationToken.ThrowIfCancellationRequested();
if (user == null)
throw new ArgumentException(nameof(user));
var res = _unitOfWork.GetRepository<User>().Get(u =>
u.Email.Equals(user.Email, StringComparison.InvariantCultureIgnoreCase)
|| user.UserName.Equals(user.UserName, StringComparison.InvariantCultureIgnoreCase))
.Select(u => u.Id)
.SingleOrDefault();
if (res == null)
throw new ArgumentOutOfRangeException(nameof(user));
return Task.FromResult(res.ToString());
}
catch (Exception ex)
{
return Task.FromResult("-1");
}
}
Related
I want to get data from a SQL Server database using a procedure passing some parameters. Is this the right way to do this? The code shown here is not working. Is there any way to get data ?
I want to call
Controller:
[Route("api/[controller]")]
[ApiController]
public class ReportController : ControllerBase
{
public IConfiguration Configuration { get; }
private readonly DatabaseContext _context;
public ReportController(IConfiguration configuration, DatabaseContext context)
{
Configuration = configuration;
_context = context;
}
[Route("AllCollectionReport")]
[HttpGet]
public IActionResult CollectionReport()
{
DataTable dt = new DataTable();
string imsConn = Configuration["ConnectionStrings:IMSConnection"];
using (SqlConnection con = new SqlConnection(imsConn))
{
string query = "KK_SP_VIEWREPO"; //<-- Here is the procedure
using (SqlCommand cmd = new SqlCommand(query))
{
cmd.Connection = con;
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
sda.Fill(dt);
}
}
}
return Ok(dt);
}
}
SQL query:
CREATE PROCEDURE KK_SP_VIEWREPO
AS
BEGIN
SELECT *
FROM KK_SalesEntry
END
This is the error what I got after get calling the method in Postman - is anything wrong with this code?
Get: https://localhost:44372/api/Report/AllCollectionReport
Error: System.Text.Json.JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32.
at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_SerializerCycleDetected(Int32 maxDepth)
at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
at System.Text.Json.JsonSerializer.WriteAsyncCore(Stream utf8Json, Object value, Type inputType, JsonSerializerOptions options, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
HEADERS
Accept: */*
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Host: localhost:44372
User-Agent: PostmanRuntime/7.26.5
Postman-Token: d65e0dd3-3c9d-4066-ba8f-db7940509c60
Help me.. :-(
You cannot return DataTable. It is not serializable. You can return Strongly Typed object.
something like this may help
List<Object> objList = new List<Object>();
using (SqlCommand cmd = new SqlCommand(query))
{
cmd.Connection = con;
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read()) {
objList.Add(new {
UserId = reader[0].ToString()
UserName = raeder[1].ToString()
});
}
}
}
return objList;
I am using apache flink 1.10 to consume RabbitMQ message and sink to MySQL using restful api, now the taskmanager exit and throw error:
2020-07-02 05:36:01,464 INFO org.apache.flink.runtime.taskmanager.Task - Source: Custom Source -> Map -> Timestamps/Watermarks (1/1) (c5607a434c6da19872cf5e0a8dda761a) switched from DEPLOYING to RUNNING.
2020-07-02 05:36:02,369 INFO org.apache.flink.runtime.taskmanager.Task - Window(TumblingEventTimeWindows(5000), EventTimeTrigger, SumField, CollectionWindow) -> Sink: Unnamed (1/1) (6dfa060a1e92735ba60e28c7e5871a56) switched from RUNNING to FAILED.
java.lang.OutOfMemoryError: Metaspace
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
at org.apache.flink.util.ChildFirstClassLoader.loadClass(ChildFirstClassLoader.java:66)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.apache.flink.util.InstantiationUtil$ClassLoaderObjectInputStream.resolveClass(InstantiationUtil.java:78)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1925)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1808)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2099)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1625)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2344)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2268)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2126)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1625)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2344)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2268)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2126)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1625)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2344)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2268)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2126)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1625)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:465)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:423)
and this is my part of Apache Flink jobs code:
public static void pumpConsumeHandler() throws Exception {
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
FlinkUtil.initEnv(env);
RMQSource dataSource = FlinkUtil.initDatasource("goblin.pump.report.realtime");
DataStream<String> dataStreamSource = env.addSource(dataSource);
DataStream<ReportPump> record =
dataStreamSource.map(new MapFunction<String, ReportPump>() {
#Override
public ReportPump map(String value) throws Exception {
ObjectMapper mapper = new ObjectMapper();
ReportPump pumpRecord = mapper.readValue(value, ReportPump.class);
return pumpRecord;
}
}).assignTimestampsAndWatermarks(new CustomAssign<ReportPump>());
record.keyBy(new KeySelector<ReportPump, Tuple2<Integer, Long>>() {
#Override
public Tuple2<Integer, Long> getKey(ReportPump value) throws Exception {
return Tuple2.of(value.getGameType(), value.getTenantId());
}
})
.timeWindow(Time.seconds(5))
.reduce(new SumField(), new CollectionWindow())
.addSink(new SinkFunction<List<ReportPump>>() {
#Override
public void invoke(List<ReportPump> reportPumps, Context context) throws Exception {
persistCollectData(reportPumps);
}
});
env.execute(PumpRealtimeHandler.class.getName());
}
public static void persistCollectData(List<ReportPump> records) throws Exception {
PumpConsumeService service = FlinkUtil.InitRetrofit().create(PumpConsumeService.class);
Call<ResponseBody> call = service.savePumpRecords(records);
ResponseBody body = call.execute().body();
String str = new String(body.bytes(), "UTF-8");
ObjectMapper mapper = new ObjectMapper();
Response response = mapper.readValue(str, Response.class);
if (!ServiceException.API_OK.equals(response.getResultCode())) {
log.error("save error:" + str);
throw new Exception();
} else {
log.debug("success:" + str);
}
}
to solve this problem, I tweak the config:
taskmanager.memory.jvm-metaspace.size: 256mb(from default 96M to 256M)
taskmanager.memory.process.size: 2g(from 1G to 2G)
I have 2 flink jobs, what should I do to avoid this problem? how much metaspace size should I config?
Using rebalance before assign watermark function affects event time processing
Configuration config = new Configuration();
StreamExecutionEnvironment see = StreamExecutionEnvironment.createLocalEnvironmentWithWebUI(config);
see.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
DataStream<String> stream = see
.addSource(new FlinkKafkaConsumer<>("testTopic3", new SimpleStringSchema(), properties));
stream.rebalance()
.map(event->{
JSONObject jsonEvent = new JSONObject(event);
Event formedEvent = new Event();
formedEvent.setTimestamp(Long.parseLong(jsonEvent.getString("time")));
System.out.println("formed event : "+formedEvent.getTimestamp());
return formedEvent;
})
.assignTimestampsAndWatermarks(new TimestampExtractor())
.keyBy(event->{
return "1";
}).window(SlidingEventTimeWindows.of(Time.seconds(5), Time.seconds(5)))
.trigger(new TriggerFunc())
.process(new ProcessWindowFunction());
see.execute();
The event time triggers don't trigger when I use rebalance. Once it is removed, it seems to work fine. Is there a reason why this does not work?
The following seems to work:
Configuration config = new Configuration();
StreamExecutionEnvironment see = StreamExecutionEnvironment.createLocalEnvironmentWithWebUI(config);
see.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
DataStream<String> stream = see
.addSource(new FlinkKafkaConsumer<>("testTopic3", new SimpleStringSchema(), properties));
stream
.map(event->{
JSONObject jsonEvent = new JSONObject(event);
Event formedEvent = new Event();
formedEvent.setTimestamp(Long.parseLong(jsonEvent.getString("time")));
System.out.println("formed event : "+formedEvent.getTimestamp());
return formedEvent;
})
.assignTimestampsAndWatermarks(new TimestampExtractor())
.rebalance()
.keyBy(event->{
return "1";
}).window(SlidingEventTimeWindows.of(Time.seconds(5), Time.seconds(5)))
.trigger(new TriggerFunc())
.process(new ProcessWindowFunction());
see.execute();
Adding my Trigger Function. My trigger function is not doing much. Just printing a statement
public class TriggerFunc extends Trigger<Event, TimeWindow>{
private static final long serialVersionUID = 1L;
#Override
public TriggerResult onProcessingTime(long time, TimeWindow window, TriggerContext ctx) throws Exception {
System.out.println("On processing time purging : " + window.getStart());
return TriggerResult.FIRE;
}
#Override
public TriggerResult onEventTime(long time, TimeWindow window, TriggerContext ctx) throws Exception {
System.out.println("On eventTime time");
return TriggerResult.FIRE_AND_PURGE;
}
#Override
public void clear(TimeWindow window, TriggerContext ctx) throws Exception {
}
#Override
public TriggerResult onElement(ThresholdEvent element, long timestamp, TimeWindow window, TriggerContext ctx)
throws Exception {
System.out.println("On element");
return TriggerResult.CONTINUE;
}
}
this is baffling me, I would appreciate some help. I have a thread that loads databases from a server in the background into a custom control that I've created.
The thread retrieves the databases just fine, but when I try to access some methods in my custom control i get thrown that exception and I don't know why!!
here's my code:
{
DatabaseLoader = new Thread(()=> AquireDatabases(LoginInfo));
DatabaseLoader.Name = "DatabaseLoader";
DatabaseLoader.IsBackground = true;
DatabaseLoader.Start();
}
private void AquireDatabases(List<Object> loginInfo)
{
DataTable dtDatabases = new DataTable();
try
{
dtDatabases = objBkp.FillCBDatabases(loginInfo[0].ToString(), loginInfo[1].ToString(), loginInfo[2].ToString());
}
catch (Exception ex)
{
string s = ex.ToString();
MessageBox.Show(s);
}
LoadDatabasesinControl(dtDatabases, null);
}
private void LoadDatabasesinControl(DataTable dtDatabases, RunWorkerCompletedEventArgs e)
{
if (InvokeRequired)
{
this.Invoke(new WorkerCompleteDelegate(LoadDatabasesinControl), dtDatabases, e);
return;
}
if (DatabaseLoader.IsAlive || !(DatabaseLoader.ThreadState == ThreadState.AbortRequested))
{
// CLEAR ALL ITEMS IN the control before filling it
serverControl.ClearControl(); // --> EXCEPTION THROWN
for (int i = 0; i < dtDatabases.Rows.Count; i++)
{
serverControl.CreateDatabase();
serverControl.DatabaseName = dtDatabases.Rows[i][0].ToString();
serverControl.lblSubDBSize = 150513; // --> EXCEPTION THROWN
}
}
}
method ClearControl() is a public method in my control, and it returns type void just like CreateDatabase()
also, lblSubDBSize is a regular public label just like DatabaseName!
Why is the exception being thrown on these two only, and none of the other functions I try to access???
I think this is a thread problem but I don't know what it is exactly.
I added my custom control as an existing project and I added the reference to it as a project to my solution instead of as a dll. I read somewhere that that could be that cause but it wasn't, I tried a bunch of stuff with no luck.
Any thoughts anyone???
[EDIT]
serverControl is a custom User Control
public Database database;
private Label lblServer;
private Button btnServerPanelExpander;
private Panel pnlServerHeader;
private List<Database> databaseCollection = new List<Database>();
public ServerControl()
{
InitializeComponent();
ControlInitializer();
}
private void ControlInitializer()
{
lblServer = new Label();
pnlServerHeader = new Panel();
btnServerPanelExpander = new Button();
btnServerPanelExpander.Click += btnServerPanelExpander_Click;
pnlServerHeader.Controls.Add(btnServerPanelExpander);
pnlServerHeader.Controls.Add(lblServer);
pnlServer.Controls.Add(pnlServerHeader);
setProperties();
}
public void ClearControl()
{
if (database == null)
return;
this.pnlServer.Controls.Clear();
this.ControlInitializer();
this.pnlServer.Invalidate();
}
public void CreateDatabase()
{
database = new Database();
database.SetIcon(DatabaseIcon);
databaseCollection.Add(database);
pnlServer.Controls.Add(database.pnlDatabase);
DrawDatabase(database);
}
and here is the stack trace and exception... hope this clarifies things
Exception Message
"Method not found: 'Void ServersControl.ServerControl.ClearControl()'."
Stack Trace
" at Forms.MainSmall.LoadDatabasesinControl(DataTable dtDatabases, RunWorkerCompletedEventArgs e)\r\n at Forms.MainSmall.AquireDatabases(List`1 loginInfo)\r\n at Forms.MainSmall.b__1370_0()\r\n at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)\r\n at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)\r\n at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n at System.Threading.ThreadHelper.ThreadStart()"
I am trying to call a WCF service from a Silverlight client using channel factory as per this link. Working with channel factory is something new for me so please bear with me!
Everything mentioned in the article works just fine. But now I am trying to implement Fault exceptions so that I can catch the actual exceptions on the Silverlight side. But for some reason I always end up catching CommunicationException which doesn't serve my purpose.
Here is my service contract:
[OperationContract]
[FaultContract(typeof(Fault))]
IList<Category> GetCategories();
Catch block of the service:
catch (Exception ex)
{
Fault fault = new Fault(ex.Message);
throw new FaultException<Fault>(fault, "Error occured in the GetCategories service");
}
Service contract for client with async pattern:
[OperationContract(AsyncPattern = true)]
[FaultContract(typeof(Fault))]
IAsyncResult BeginGetCategories(AsyncCallback callback, object state);
IList<Category> EndGetCategories(IAsyncResult result);
Here is the service call from client:
ICommonServices channel = ChannelProviderFactory.CreateFactory<ICommonServices>(COMMONSERVICE_URL, false);
var result = channel.BeginGetCategories(
(asyncResult) =>
{
try
{
var returnval = channel.EndGetCategories(asyncResult);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
CategoryCollection = new ObservableCollection<Category>(returnval);
});
}
catch (FaultException<Fault> serviceFault)
{
MessageBox.Show(serviceFault.Message);
}
catch (CommunicationException cex)
{
MessageBox.Show("Unknown Communications exception occured.");
}
}, null
);
I am sharing the DataContract .dll between both the service and client applications and hence they are referring to same data contract classes (Category & Fault)
Please tell me what I am doing wrongly?
UPDATE: I do clearly see the fault exception sent from the service in Fiddler. Which makes me believe I am missing something in the client side.
For catching normal exceptions in sivleright you must create "Silverlight-enabled WCF Service" (Add -> New Item -> Silverlight-enabled WCF Service).
If you already created standard WCF service you can add attribute [SilverlightFaultBehavior] to your service manually.
Default implementation of this attribute is:
public class SilverlightFaultBehavior : Attribute, IServiceBehavior
{
private class SilverlightFaultEndpointBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new SilverlightFaultMessageInspector());
}
public void Validate(ServiceEndpoint endpoint)
{
}
private class SilverlightFaultMessageInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
if ((reply != null) && reply.IsFault)
{
HttpResponseMessageProperty property = new HttpResponseMessageProperty();
property.StatusCode = HttpStatusCode.OK;
reply.Properties[HttpResponseMessageProperty.Name] = property;
}
}
}
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints)
{
endpoint.Behaviors.Add(new SilverlightFaultEndpointBehavior());
}
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
}
We use our own custom ServiceException class on the server e.g.
[Serializable]
public class ServiceException : Exception
{
public ServiceException()
{
}
public ServiceException(string message, Exception innerException)
: base(message, innerException)
{
}
public ServiceException(Exception innerException)
: base("Service Exception Occurred", innerException)
{
}
public ServiceException(string message)
: base(message)
{
}
}
And then in our server side service methods we use error handling like this:
try
{
......
}
catch (Exception ex)
{
Logger.GetLog(Logger.ServiceLog).Error("MyErrorMessage", ex);
throw new ServiceException("MyErrorMessage", ex);
}
We then use a generic method for all web service calls:
/// <summary>
/// Runs the given functon in a try catch block to wrap service exception.
/// Returns the result of the function.
/// </summary>
/// <param name="action">function to run</param>
/// <typeparam name="T">Return type of the function.</typeparam>
/// <returns>The result of the function</returns>
protected T Run<T>(Func<T> action)
{
try
{
return action();
}
catch (ServiceException ex)
{
ServiceLogger.Error(ex);
throw new FaultException(ex.Message, new FaultCode("ServiceError"));
}
catch (Exception ex)
{
ServiceLogger.Error(ex);
throw new FaultException(GenericErrorMessage, new FaultCode("ServiceError"));
}
}