Can anyone tell me how to find available agent containers through java code? I am using the JADE agent framework and I have figured out how to create new containers but not find existing containers (so that agents can be deployed in them).
There are two ways of doing this, depending on whether you want to receive the information via an ongoing service or the current snapshot in a message.
To get a snapshot of the IDs of the currently available agent containers, send a Request message to the Agent Management Service (AMS) and wait for its reply. Using the JADE Management Ontology and the QueryPlatformLocationsAction term, the sending and receiving methods would be:
private void queryAMS() throws CodecException, OntologyException {
QueryPlatformLocationsAction query = new QueryPlatformLocationsAction();
Action action = new Action(myAgent.getAID(), query);
ACLMessage message = new ACLMessage(ACLMessage.REQUEST);
message.addReceiver(myAgent.getAMS());
message.setLanguage(FIPANames.ContentLanguage.FIPA_SL);
message.setOntology(JADEManagementOntology.getInstance().getName());
myAgent.getContentManager().fillContent(message, action);
myAgent.send(message);
}
private void listenForAMSReply() throws UngroundedException, CodecException,
OntologyException {
ACLMessage receivedMessage = myAgent.blockingReceive(MessageTemplate
.MatchSender(myAgent.getAMS()));
ContentElement content = myAgent.getContentManager().extractContent(
receivedMessage);
// received message is a Result object, whose Value field is a List of
// ContainerIDs
Result result = (Result) content;
List listOfPlatforms = (List) result.getValue();
// use it
Iterator iter = listOfPlatforms.iterator();
while (iter.hasNext()) {
ContainerID next = (ContainerID) iter.next();
System.out.println(next.getID());
}
}
To get this information as an ongoing service, and to receive the ContainerID of each container as it registers with the AMS, create a Behaviour that extends the AMSSubscriber. Register a handler for the AddedContainer event and you will be able to access the ContainerID of the newly available container:
public class AMSListenerBehaviour extends AMSSubscriber {
#Override
public void installHandlers(Map handlersTable) {
handlersTable.put(AddedContainer.NAME, addedContainerHandler);
}
public final class AddedContainerHandler implements EventHandler {
#Override
public void handle(Event ev) {
AddedContainer event = (AddedContainer) ev;
ContainerID addedContainer = event.getContainer();
System.out.println(addedContainer.getID());
}
Hope this helps,
Russ
Related
I will insert logs from exception handler and i've action for post logs. How can I call my service action properly?
Is creating instance everytime correct?
public class CustomExceptionHandler : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
var exceptionModel = new System_Logs() { Date = DateTime.Now, Request = actionExecutedContext.Request.RequestUri.AbsoluteUri, Response = actionExecutedContext.Response.Content.ToString()};
System_LogsController controller = new System_LogsController();
controller.PostSystem_Logs(exceptionModel);
base.OnException(actionExecutedContext);
}
}
You should create a logging service class (not a controller class) that will handle logging. If you are using dependency injection, for custom filter attributes use property injection using the [Dependency] annotation/decorator to the property. This logging service will be initialized via injection container. You can search in SO for IoC (e.g Unity, autofac, ninject, etc) to help you get started. It's worth knowing this IoC and dependency injection principles as it can apply both on the server side and in the client side(javascript development).
To elaborate on what you currently have. Your code above will look like something like:
public class CustomExceptionHandler : ExceptionFilterAttribute
{
[Dependency]
public ILoggingService LoggingService { get; set; }
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
var exceptionModel = new System_Logs() { Date = DateTime.Now, Request = actionExecutedContext.Request.RequestUri.AbsoluteUri, Response = actionExecutedContext.Response.Content.ToString()};
LoggingService.PostSystemLogs(exceptionModel);
base.OnException(actionExecutedContext);
}
}
I'm using JavaFX to create a basic GUI. I have a database created in MySQL to store the data. (DBConnect) (connector/j)
This is my very first attempt at connecting the two, as well as using ResultSets/DBConnect
Currently, I have 3 Classes: my Game class, my GameUI class (main), and my DBConnect class.
I am attempting to Reference the ResultSet in my GameUI class, that was originally declared in Game class.
public class Game {
private static DBConnect dbc;
private static Connection conn;
public ResultSet rs;
int id;
String name;
float price;
String vendor;
int rating;
public Game() {
try {
conn = dbc.connect();
String SQL = "Select * from Person";
rs = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE).executeQuery(SQL);
System.out.println("list result set for record..");
printRs(rs);
} catch(SQLException ignore) {
}
}
My User Defined moveNext() method:
public Game moveNext() {
Game g = new Game();
try {
if(rs.next() == false)
rs.previous();
g.setGameId(rs.getInt("gameId"));
g.setGameName(rs.getString("gameName"));
g.setPrice(rs.getFloat("price"));
g.setVendor(rs.getString("vendor"));
g.setRating(rs.getInt("rating"));
} catch(SQLException e) {
e.printStackTrace();
}
return g;
}
The GameUI class i am trying to reference it in:
public class GameUI extends Application {
private Button firstButton = new Button("First");
private Button createButton = new Button("Create");
private Button updateButton = new Button("Update");
private Button deleteButton = new Button("Delete");
private Button lastButton = new Button("Last");
private Button nextButton = new Button("Next");
private Button prevButton = new Button("Prev");
GridPane grid = new GridPane();
HBox hbox = new HBox(14);
private static DBConnect dbc;
private static Connection conn;
// private static
private Pane initButtons() {
hbox.getChildren().addAll(firstButton, createButton, updateButton, deleteButton, lastButton, nextButton, prevButton);
nextButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
Game.rs.moveNext();
}
});
return hbox;
}
My Question is, can I Reference my ResultSet (Game class) in my nextButton event handler (my GameUI class) OR do I have to declare a new result set?
Is this the right place for my user defined moveNext() method, or should I use next()?
I will post more code on request.
You can pass the result set further, but it is bad practice (See Is it Ok to Pass ResultSet?). From what I see from the code you posted it is mainly an issue with the layering of the different parts of the application, that should be separated:
Database related code belong into one layer. No other layer should directly talk to the DB or handle any DB specific objects. To achieve this the DBConnection class should handle all database related stuff. To pass data from the database to the other layers and vice versa you use a data transfer object (DTO) which is basically an object representation of a specific result set. Usually this boils down to one DTO per database table.
Then you have an intermediate layer, lets call it service layer, which is used to communicate from the UI to the database and do some computation.
On top of that you have the UI layer where your application lives. Here you have to consider which actions belong into that layer and what should better be delegated to the service layer.
Take also a look at this wikipedia article: https://en.wikipedia.org/wiki/Multitier_architecture
There's a project called Web App Template (aka WAT - http://wat.codeplex.com/) that allows you to wrap a webapp as a Windows 8 / Windows Phone 8 application. I've done that to an app, now I'm trying to add the "rate my app" feature to it. I don't see where/if I can inject code for this component to be added.
I'm following a guide here: http://developer.nokia.com/community/wiki/Implement_%22Rate_My_App%22_in_under_60_seconds
I'm stuck at Step 5 - where do I add the Event Handler? There is no MainPage.xaml.cs and I don't see any similar files.
I imagine that WAT is calling another library to load a web browser. Is there some way I can inject an Event Handler and method into this library?
I suggest not to prompt the user with 'rate my app' thing in the first opening of the app as user should be given some time to see what the app looks like and how it functions. Therefore, keeping the number of app launches and asking to rate the app after some 5th - 10th launch of app will make more sense. Besides you should check if you already prompted the user to rate your app, if so never prompt again. (Otherwise you will piss them off with 'rate my app' thing)
In order to achieve this, you should at first keep the app launch count in app settings class.
The interface for storing any kind of setting:
public interface ISettingService
{
void Save();
void Save(string key, object value);
bool AddOrUpdateValue(string Key, object value);
bool IsExist(string key);
T Load<T>(string key);
T GetValueOrDefault<T>(string Key, T defaultValue);
}
The rating service class that consumes the above interface to store such count and settings:
public class RatingService
{
private const string IsAppRatedKeyName = "isApprated";
private const string TabViewCountKeyName = "tabViewCount";
private const bool IsAppratedDefault = false;
private const int TabViewCountDefault = 0;
private const int ShowRatingInEveryN = 7;
private readonly ISettingService _settingService;
[Dependency]
public RatingService(ISettingService settingService)
{
_settingService = settingService;
}
public void RateApp()
{
if (_settingService.AddOrUpdateValue(IsAppRatedKeyName, true))
_settingService.Save();
}
public bool IsNeedShowMessage()
{
return (_settingService.GetValueOrDefault(TabViewCountKeyName, TabViewCountDefault)%ShowRatingInEveryN) == 0;
}
public void IncreaseTabViewCount()
{
int tabCount = _settingService.GetValueOrDefault(TabViewCountKeyName, TabViewCountDefault);
if (_settingService.AddOrUpdateValue(TabViewCountKeyName, (tabCount + 1)))
_settingService.Save();
}
public bool IsAppRated()
{
return _settingService.GetValueOrDefault(IsAppRatedKeyName, IsAppratedDefault);
}
}
This is how you will run such functionality and prompt the user to rate the app (if previously not rated) anywhere in your project (mainpage or some other page where user launches some functionality):
private void RunRating()
{
if (!RatingService.IsAppRated() && RatingService.IsNeedShowMessage())
{
MessageBoxResult result = MessageBox.Show("Review the app?", "Would you like to review this awesome app?",
MessageBoxButton.OKCancel);
//show message.
if (result == MessageBoxResult.OK)
{
RatingService.RateApp();
new MarketplaceReviewTask().Show();
}
}
}
I've created a multi-threaded service that uses Castle Windsor to create components to run on separate threads. I Resolve an component by name with parameters for each thread.
I'm running into concurrency problems with a 3rd party library used by the components. I suspect that isolating those components in separate AppDomains will resolve the problem.
Is there a way to have Resolve create the component using a different AppDomain?
private ActivityThread NewActivityThread(ActivityInstance activityInstance)
{
// Set up the creation arguments.
System.Collections.IDictionary arguments = new Dictionary<string, string>();
activityInstance.Parameters.ForEach(p => arguments.Add(p.Name, p.Value));
// Get the activity handler from the container.
IActivity activity = Program.Container.Resolve<IActivity>(activityInstance.Name, arguments);
// Create a thread for the activity.
ActivityThread thread = new ActivityThread(activity, activityInstance, _nextActivityID++);
return thread;
}
public ActivityThread(IActivity activity, ActivityInstance instance, int id)
{
_activity = activity;
_instance = instance;
_id = id;
}
public void Start()
{
if (_thread == null)
{
// Create a new thread to run this activity.
_thread = new Thread(delegate() { _activity.Run(); });
_thread.Name = _activity.ToString();
_thread.SetApartmentState(ApartmentState.STA);
_thread.Start();
}
}
Try the remoting facility. See:
http://www.castleproject.org/container/facilities/trunk/remoting/index.html
http://gojko.net/2008/07/09/really-simple-net-remoting-with-castle/
If you've already created a separate AppDomain, can't you just create a new instance of a Windsor container within the private AppDomain?
I have a group of classes that implement an interface for my application start-up activities. Here is the registration code:
private static void ConfigureContainer()
{
var container = new WindsorContainer();
container.Register(AllTypes.Of<IStartupTask>()
.FromAssembly(Assembly.GetExecutingAssembly()))
...
var serviceLocator = container.Resolve<IServiceLocator>();
ServiceLocator.SetLocatorProvider(() => serviceLocator);
}
In order to get the tasks, I use this and it works as expected:
public static void Run()
{
var tasks = ServiceLocator.Current.GetAllInstances<IStartupTask>();
foreach (var task in tasks)
{
task.Execute();
}
}
Here is my problem: I have one task that depends on another being run first. There is an InitializeDatabase task that needs to run before the PopulateDatabse task. There are also a bunch of other tasks that are run and I would rather not split the InitializeDatabase task out, if there is some Castle config that will allow me to order the resolution of the types. I don't want to specify the complete order of the types being resolved since that defeats the purpose of the automatic registration, just that InitializeDatabase is the first or PopulateDatabase is last.
Is there a way to register which types should be resolved first without specifying the order of all the types?
Here's one way to do it, it might not be very pretty but it works:
[AttributeUsage(AttributeTargets.Class)]
public class FirstAttribute: Attribute {}
public interface IService {}
public class ThirdService : IService { }
[First]
public class FirstService : IService { }
public class SecondService: IService {}
[Test]
public void WindsorOrder() {
var container = new WindsorContainer();
container.Register(AllTypes.Of<IService>()
.FromAssembly(Assembly.GetExecutingAssembly()));
var intf = container.ResolveAll<IService>()
.OrderByDescending(i => i.GetType().GetCustomAttributes(typeof(FirstAttribute), true).Length)
.ToArray();
Assert.IsInstanceOfType(typeof(FirstService), intf[0]);
}
If you remove [First] from FirstService, the first will be ThirdService and the test will fail.
Use HandlerSelector for that