Sparx Enterprise architect Create baseline using powershell - powershell-2.0

I want to automatically create a baseline for each project in my enterprise architect project using PowerShell.
How do you create a baseline from PowerShell?
My code so far gets all the models IE high-level packages for which I want to create a new baseline.
$conString = "private connection string"
## implementation do not chage
add-type -path “C:\Program Files (x86)\Sparx Systems\ea\Interop.EA.dll”
$ea = New-Object -ComObject EA.Repository
$ea.OpenFile($conString);
function Process-Packages($packages)
{
if(!$packages) { throw [System.ArgumentNullException]::new('packages'); }
if(0 -ge $packages.Count) { return; }
## create a baseline for each package
}
foreach($model in $ea.models)
{
Process-Packages $model.packages;
}
$ea.CloseFile();
$ea.Exit();
Update:
While using VS I have found the object I am looking for is under EA.ProjectClass
which is exposing the relevant functionality to create a package:
public virtual bool CreateBaseline(string PackageGUID, string Version, string Notes)
Member of EA.ProjectClass
Summary:
Creates a baseline on the specified package.
Attributes:
[System.Runtime.InteropServices.DispIdAttribute(66)]
and there is relative implementation to getbaselines
public virtual string GetBaselines(string PackageGUID, string ConnectString)
Member of EA.ProjectClass
Summary:
Returns an xml string containing the list of guids available for that package.
Attributes:
[System.Runtime.InteropServices.DispIdAttribute(65)]

Ok after going through internet dll's I have found an anwer to my question.
The solution is rather simple, but getting there was painful.
Please note, not all fields such as Author are populated and additional work is required to make it fully usable solution. This process does bypass configured security for packages.
RAW Implementation of the script
add-type -path “C:\Program Files (x86)\Sparx Systems\ea\Interop.EA.dll”
$ea = New-Object -ComObject EA.Repository
$ea.OpenFile("private db connection string");
foreach($model in $ea.models)
{
$eaProject = $ea.GetProjectInterface()
$eaProject.CreateBaseline($model.PackageGUID,"9.9.9","PowerShell generated")
}
$ea.CloseFile();
$ea.Exit();
Processing info
As mentioned in comments it is time consuming process. For me running this PowerShell on 22k objects it takes about an hour on i3 intel / 4GB RAM

Related

Are TFS Build Agent User Capabilities' Values Obtainable Within Build Steps?

I'm trying to write a build step within TFS that relies on knowing where the Build agent has nuget.exe stored (the standard nuget-install step mucks around with the order of arguments in a way that breaks build execution, so I want to run the exe myself using one of the batch/shell/ps steps).
It would seem that setting up a capability on the Build Agent with that path would make sense, but I cannot seem to reference the value in any of my build steps, and I cannot find anything helpful on MSDN.
I'm expecting it to be something like $(Env.MyUserCapability), but it never resolves to the value.
Is it possible to retrieve a capability value within a build step? And if so, how do you do it? And if not, what is a viable alternative?
The user-defined capabilities are metadata only. But you can set a global environment variable (e.g. NUGET) and set that to a path to a nuget.exe, when you restart the agent, the machine-wide environment is then discovered as capability and you can then use it.
If you are writing a custom task, you can also add a nuget.exe to the task that will be downloaded to the executing agent.
UPDATE: I made a public extension out of this.
UPDATE: this works in Azure DevOps 2019.
In TFS 2018u1, the following works:
Import-Module "Microsoft.TeamFoundation.DistributedTask.Task.Common"
Import-Module "Microsoft.TeamFoundation.DistributedTask.Task.Internal"
Add-Type -Assembly "Microsoft.TeamFoundation.DistributedTask.WebApi"
$VSS = Get-VssConnection -TaskContext $distributedTaskContext
$AgentCli = $VSS.GetClient([Microsoft.TeamFoundation.DistributedTask.WebApi.TaskAgentHttpClient])
$AgentConfig = Get-Content "$Env:AGENT_HOMEDIRECTORY\.agent" -Raw | ConvertFrom-Json
$Agent = $AgentCli.GetAgentAsync($AgentConfig.PoolId, $Env:AGENT_ID, $TRUE, $FALSE, $NULL, $NULL, [System.Threading.CancellationToken]::None).GetAwaiter().GetResult()
if($Agent.UserCapabilities.MyCapability)
{
Write-Host "Got the capability!";
}
The long string of default arguments ending with CancellationToken::None is for compatibility with Powershell 4. PS4 doesn't support default values for value-typed method parameters, PS5 does.
This snippet does something very questionable - it relies on the location and the structure of the agent configuration file. This is fragile. The problem is that the GetAgentAsync method requires both pool ID and the agent ID, and the former is not exposed in the environment variables. A slightly less hackish approach would check all pools and find the right one by the agent ID:
$Pools = $AgentCli.GetAgentPoolsAsync($NULL, $NULL, $NULL, $NULL, $NULL, [System.Threading.CancellationToken]::None).GetAwaiter().GetResult()
$Demands = New-Object 'System.Collections.Generic.List[string]'
foreach($Pool in $Pools)
{
$Agent = $AgentCli.GetAgentsAsync($Pool.ID, $Env:AGENT_NAME, $TRUE, $FALSE, $NULL, $Demands, $NULL, [System.Threading.CancellationToken]::None).Result
if($Agent -and $Agent.Id -eq $Env:AGENT_ID)
{
Break
}
}
This relies on another undocumented implementation detail, specifically that agent IDs are globally unique. This seems to hold as late as TFS 2018, but who knows.
When you employ the $distributedTaskContext, the task is connecting back to TFS with an artificial user identity, "Project Collection Build Service" (not with the agent service account). There's one user like that in each collection, they're distinct. In order to allow tasks running in releases in a collection to query the agent for user capabilities, you need to grant the Reader role to the relevant pool(s) (or all pools) to the user account called "Project Collection Build Service (TheCollectionName)" from that collection.
It also looks like some actions also grant an implicit Reader role on a pool to the task identity.
Alternatively, you can construct a VssConnection from scratch with Windows credentials, and grant the agent account(s) Reader role on the pool(s).

How do I deal with WS-Security when all I have is a wsdl?

I'm trying to develop a stand-alone client app that uses web services in a Glassfish container (Metro). About all I have to work from is a wsdl for the wervices I'm trying to use. The wsdl is rife with all kinds of 'wsp:Policy' tags. Looks like IssuedToken, Trust13, ecryption are all utilized.
So I generated some code from netbeans and JAX-WS. Everything went well, but when trying to run the client I get:
'WST0029:STS location could not be obtained from either IssuedToken or from client configuration for accessing the service http://localhost:8080/ ....'
That's when it occured to me that I know nothing about WSS. It doesn't look like any code was generated to deal with security. So, I'll have to go from scratch.
So where to start? Books? Tutorials?
TIA
Metro applies the policy in runtime from either the WSDL or the wsit-client.xml config file. That's why no code is generated related to policies. According to this post it is not possible at the moment to do programatically.
This tutorial explains pretty well some of the things you can do with WSS, and though everything do probably not apply in this case it's still a good read.
The simplest way I've found of generating a client with WSS support is by using the wsimport script from Metro:
cd metro/bin/
mkdir src target
./wsimport.sh -s src -d target -extension -Xendorsed -verbose YourService.wsdl
Then install Metro into your application server (copy the libs to the correct places or run the ant script):
ant -f metro-on-glassfish.xml
Then put your local WSDL file in your classpath (e.g. your resource folder), so Metro can get it at runtime to apply the policies from your generated YourService class:
private final static URL YOURSERVICE_WSDL_LOCATION;
// This is enough, you don't need the wsdlLocation attribute
// on the #WebServiceClient annotation if you have this.
static {
YOURSERVICE_WSDL_LOCATION =
CustomerService.class.getClassLoader().getResource("YourService.wsdl");
}
public YourService() {
super(YOURSERVICE_WSDL_LOCATION,
new QName("http://tempuri.org/", "YourService"));
}
And if you want WS-Addressing you might need to add the feature manually to your binding method (Metro has never generated it for me, so I always have to add it myself).
#WebEndpoint(name = "WSHttpBinding_IYourService")
public IYourService getWSHttpBindingIYourService() {
WebServiceFeature wsAddressing = new AddressingFeature(true);
IYourService service =
super.getPort(new QName("http://xmlns.example.com/services/Your",
"WSHttpBinding_IYourService"), IYourService.class,
wsAddressing);
return service;
}

Why Java Web Service Client (CXF, JAX-WS, JDK1.6) Exhibits Different Behavior in Grails app? A CLASSPATH fix?

BACKGROUND:
Current Grails application has to interact w/ a 'legacy' web service
from a third party vendor - (systinet) Used the Apache CXF
Wsdl2Java tool to generate complex types and service interfaces.
Pretty standard stuff so far and this works perfectly from Java.
After writing some test classes and main() methods to
exercise the Java code, and providing a thin layer above for a
simplified interface, I wanted to call this code from Grails app.
Specifically, Grails controllers, services, quartz jobs ,and the
like. However, this is where things got interesting.
First stack trace from Grails CXF plug-in it was causing a FileNotFoundException. Beyond not needing to load a WSDL definition - since I already successfully ran CXF's Wsdl2Java tool, it seems there is something I'm missing here. Tried substituting a file:/// url***for the WSDL and got another exception.
At the end of all this -- removing plug-ins of any sort, I reconfigured the project with the CXF dependencies by hand** and now got a MarshallingException, essentially from the CXF-generated code! Which by the way executes perfectly from a Java class.
Someone I am sure must've come across this issue in your Grails integrations. As always your guidance is most appreciated!
1)Why in the Grails application, does the runtime attempt to parse the wsdl ? Also, note JDK versions are same java version "1.6.0_12".
2) Any CLASSPATH workarounds anyone can suggest? I guess an alternative approach is to re-write the Java middle layer calls with GroovyWS but that would be quite an effort - given number of services and the custom types the vendor has baked in.
static {
URL url = null;
try {
url = new URL("http://mydevhost:9080/wasp/bmc-security/ctsa/person");
} catch (MalformedURLException e) {
System.err.println("Can not initialize the default wsdl from server");
// e.printStackTrace();
}
WSDL_LOCATION = url;
}
/* static {
URL url = null;
try {
url = new URL( "file:///C:/Projects/beta/workspace/reqmgr3/wsdl/Person.wsdl" );
url.getPath();
} catch (MalformedURLException e) {
System.err.println("Can not initialize the default wsdl from file system");
// e.printStackTrace();
}
WSDL_LOCATION = url;
} */
`
****Stack traces
INFO: No Trust Decider configured for Conduit ...
Aug 11, 2010 6:26:16 PM org.apache.cxf.transport.http.HTTPConduit finalizeConfig
INFO: No Basic Auth Supplier configured for Conduit '...
Aug 11, 2010 6:26:16 PM org.apache.cxf.transport.http.HTTPConduit prepare
INFO: Chunking is set at 2048.
Aug 11, 2010 6:26:16 PM org.apache.cxf.phase.PhaseInterceptorChain doIntercept
INFO: Interceptor has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Marshalling Error: com.systinet.wsdl.com.bmc.security.ess.webservice.holder.ArrayOfLog
inPairHolder is not known to this context
at org.apache.cxf.jaxb.JAXBEncoderDecoder.marshall(JAXBEncoderDecoder.java:132)
at org.apache.cxf.jaxb.io.XMLStreamDataWriter.write(XMLStreamDataWriter.java:42)
at org.apache.cxf.jaxb.io.XMLStreamDataWriter.write(XMLStreamDataWriter.java:30)
at org.apache.cxf.interceptor.BareOutInterceptor.handleMessage(BareOutInterceptor.java:73)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:148)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:215)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:122)
at $Proxy44.login(Unknown Source)
...
... 2 more
UPDATE 15-Aug:
Decided, out of both modularity and expediency, to put this code into separate WAR project, which will offer its ltd. services, rather than expose the original vendor web services, which are too unwieldy.
This project will be pure Java and leverages the Metro 2.0.1 runtime, which is around 16mb.
Calling the Java-based middleware services from Grails now becomes possible, after clearing out the lib and src/java folders -- basically just installed ws-client plugin and setup local services such as the following:
import groovyx.net.ws.WSClient
import org.grails.plugins.wsclient.service.WebService
class LocalPersonService {
WebService webService
groovyx.net.ws.WSClient _proxy
static final String PERSON_WSDL_URL = "http://localhost:9090/pri/PersonServicePort?wsdl"
def transactional = false
def getPersonDetails( String customerId, User userAccount, String userCredential ) {
// must cache the proxy
if ( _proxy == null ) {
print( "init proxy. Parsing wsdl..." )
try {
_proxy = webService.getClient(PERSON_WSDL_URL)
}
catch ( Throwable tr ) { println( tr.getMessage() ) }
}
// method shall return a (com.siventures.example.service.PersonDetails)
return _proxy.getPersonDetails( customerId, userAccount, userCredential, ... )
}

Unit Test Adapter threw exception: Unable to load one or more... in ASP.NET MVC

Using ASP.NET MVC 1.0 (current) I create a new default ASP.NET MVC project using Visual Studio 2008 on an x64 machine (Server 2008) and accept all the defaults and build and run it. Apart from having to set the System.Web.* assemblies as "Copy Local" it runs and brings up the default web app. When I try and run the unit tests on this project I get:
Unit Test Adapter threw exception: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information..
Now if I repeat the same exercise using VS2008 on an x86 machine (Server 2003) then all 27 default unit tests run fine. (Also I don't need to mark the System.Web.* assemblies as "Copy Local")
Ideas for resolving the exception?
More Info:
After trying some of the solutions suggested I started commenting out parts of the boilerplate test code that is generated with a new project. As such, I believe that the error is being generated by the inclusion of one of the following classes:
public class MockIdentity : IIdentity
{
public string AuthenticationType
{
get
{
return "MockAuthentication";
}
}
public bool IsAuthenticated
{
get
{
return true;
}
}
public string Name
{
get
{
return "someUser";
}
}
}
public class MockPrincipal : IPrincipal
{
IIdentity _identity;
public IIdentity Identity
{
get
{
if (_identity == null)
{
_identity = new MockIdentity();
}
return _identity;
}
}
public bool IsInRole(string role)
{
return false;
}
}
public class MockMembershipUser : MembershipUser
{
public override bool ChangePassword(string oldPassword, string newPassword)
{
return newPassword.Equals("newPass");
}
}
public class MockHttpContext : HttpContextBase
{
private IPrincipal _user;
public override IPrincipal User
{
get
{
if (_user == null)
{
_user = new MockPrincipal();
}
return _user;
}
set
{
_user = value;
}
}
}
First, have you tried it in Release configuration? Have you done a clean on your solution?
Have you tried constructing your test project? Take out the source files for your tests, delete the project from your solution and add a new test project that references the MVC app. Then re-add the test source files.
Edit
Are the classes and interfaces that you are using and implementing in scope from your tests?
Edit
Is it referencing the x64 not the x86 dlls?
Do you have VS 2008 SP1 and .NET 3.5 SP1 installed in your Win2k8 box? By default VS 2008 installed 3.5 framework, but NOT SP1. Make sure you have both the framework SP1 and VS 2008 SP1 installed.
Did you try building your project as x86 project (Project properties ->Build ->Platform target) on x64 machine?
Also, not sure about your unit testing toolkit, but NUnit, for example, can run as tests as either x86 or x64 (on x64 machine). If one of your assemblies accesses some 32-bit code (e.g. COM object), trying to run them under x64 will result in "Unable to load one or more of the requested types" error.
I'm not sure about the subtleties of what's going on with the x64 verus x86, but using custom identity/principals can cause some interesting little glitches to happen, especially if using cassini (the built-in vshost webserver - which I think is what you end up using by running local unit tests within VS). I ran into this issue before, and rather than detailing it here, I'll post a link to some good info. Again, I'm not sure if this is related to your problem (my not being an MVC guru), but take a read through this. Food for thought:
http://www.lhotka.net/weblog/UpdateOnMyStrugglesWithTheASPNETDevelopmentServer.aspx
EDIT: so ultimately, this may be an issue of serialization failure, even if this particular edge case is not relevant. Have you tried marking your mocked iidentity/iprincpal objects as [serializable]? Remember that visual studio is a 32bit application; perhaps testing it on IIS (if not cassini) with a 64bit application pool is causing a context switch somewhere which causes the mock identities (if they get assigned as a thread's identity) to get marshalled across a boundary like that - the lack of a [serializable] attribute will probably cause a TypeLoadException.
Does it still throw if you set IIS to use a 32bit application pool (on your 64bit server)?
-Oisin
I'm wondering if the more significant difference is 2k8 vs 2k3 than 64 vs 32bit. Did you spawn Visual Studio as Administrator? An assembly might be missing due to the Virtual Store of windows 2k8. If this is a development desktop running 2k8 you might want to consider disabling the Virtual Store, it's in you policy labeled as "User Account Control: Virtualize file and registry write failures to per-user locations"
I notice some of the types (specifically IIdentity and IPrincipal) you are implementing are not located within a System.Web.* assembly.
Have you tried marking the System.Security.Principal assembly as "Copy Local"?
This reminded me of an old blog post I once read. Perhaps you can use the same technique to debug the cause of the error:
http://www.agileprogrammer.com/oneagilecoder/archive/2007/11/17.aspx

How to monitor a text file in realtime [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
For debugging purposes in a somewhat closed system, I have to output text to a file.
Does anyone know of a tool that runs on windows (console based or not) that detects changes to a file and outputs them in real-time?
I like tools that will perform more than one task, Notepad++ is a great notepad replacement and has a Document Monitor plugin (installs with standard msi) that works great. It also is portable so you can have it on a thumb drive for use anywhere.
For a command line option, PowerShell (which is really a new command line) has a great feature already mentioned.
Get-Content someFile.txt -wait
But you can also filter at the command line using a regular expression
Get-Content web.log -wait | where { $_ -match "ERROR" }
Tail for Win32
Apache Chainsaw - used this with log4net logs, may require file to be in a certain format
When using Windows PowerShell you can do the following:
Get-Content someFile.txt -wait
I use "tail -f" under cygwin.
I use BareTail for doing this on Windows. It's free and has some nice features, such as tabs for tailing multiple files and configurable highlighting.
Tail is the best answer so far.
If you don't use Windows, you probably already have tail.
If you do use Windows, you can get a whole slew of Unix command line tools from here. Unzip them and put them somewhere in your PATH.
Then just do this at the command prompt from the same folder your log file is in:
tail -n 50 -f whatever.log
This will show you the last 50 lines of the file and will update as the file updates.
You can combine grep with tail with great results - something like this:
tail -n 50 -f whatever.log | grep Error
gives you just lines with "Error" in it.
Good luck!
FileSystemWatcher works a treat, although you do have to be a little careful about duplicate events firing - 1st link from Google - but bearing that in mind can produce great results.
Late answer, though might be helpful for someone -- LOGEXPERT seems to be interesting tail utility for windows.
Try SMSTrace from Microsoft (now called CMTrace, and directly available in the Start Menu on some versions of Windows)
Its a brilliant GUI tool that monitors updates to any text file in real time, even if its locked for writing by another file.
Don't be fooled by the description, its capable of monitoring any file, including .txt, .log or .csv.
Its ability to monitor locked files is extremely useful, and is one of the reasons why this utility shines.
One of the nicest features is line coloring. If it sees the word "ERROR", the line becomes red. If it sees the word "WARN", the line becomes yellow. This makes the logs a lot easier to follow.
I have used FileSystemWatcher for monitoring of text files for a component I recently built. There may be better options (I never found anything in my limited research) but that seemed to do the trick nicely :)
Crap, my bad, you're actually after a tool to do it all for you..
Well if you get unlucky and want to roll your own ;)
Yor can use the FileSystemWatcher in System.Diagnostics.
From MSDN:
public class Watcher
{
public static void Main()
{
Run();
}
[PermissionSet(SecurityAction.Demand, Name="FullTrust")]
public static void Run()
{
string[] args = System.Environment.GetCommandLineArgs();
// If a directory is not specified, exit program.
if(args.Length != 2)
{
// Display the proper way to call the program.
Console.WriteLine("Usage: Watcher.exe (directory)");
return;
}
// Create a new FileSystemWatcher and set its properties.
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = args[1];
/* Watch for changes in LastAccess and LastWrite times, and
the renaming of files or directories. */
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
// Only watch text files.
watcher.Filter = "*.txt";
// Add event handlers.
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
// Begin watching.
watcher.EnableRaisingEvents = true;
// Wait for the user to quit the program.
Console.WriteLine("Press \'q\' to quit the sample.");
while(Console.Read()!='q');
}
// Define the event handlers.
private static void OnChanged(object source, FileSystemEventArgs e)
{
// Specify what is done when a file is changed, created, or deleted.
Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
}
private static void OnRenamed(object source, RenamedEventArgs e)
{
// Specify what is done when a file is renamed.
Console.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath);
}
}
You can also follow this link Watching Folder Activity in VB.NET
Snake Tail. It is a good option.
http://snakenest.com/snaketail/
Just a shameless plug to tail onto the answer, but I have a free web based app called Hacksaw used for viewing log4net files. I've put in an auto refresh options so you can give yourself near real time updates without having to refresh the browser all the time.
Yeah I've used both Tail for Win32 and tail on Cygwin. I've found both to be excellent, although I prefer Cygwin slightly as I'm able to tail files over the internet efficiently without crashes (Tail for Win32 has crashed on me in some instances).
So basically, I would use tail on Cygwin and redirect the output to a file on my local machine. I would then have this file open in Vim and reload (:e) it when required.
+1 for BareTail. I actually use BareTailPro, which provides real-time filtering on the tail with basic search strings or search strings using regex.
To make the list complete here's a link to the GNU WIN32 ports of many useful tools (amongst them is tail).
GNUWin32 CoreUtils
Surprised no one has mentioned Trace32 (or Trace64). These are great (free) Microsoft utilities that give a nice GUI and highlight any errors, etc. It also has filtering and sounds like exactly what you need.
Here's a utility I wrote to do just that:
It uses a FileSystemWatcher to look for changes in log files within local folders or network shares (don't have to be mounted, just provide the UNC path) and appends the new content to the console.
on github: https://github.com/danbyrne84/multitail
http://www.danielbyrne.net/projects/multitail
Hope this helps
#echo off
set LoggingFile=C:\foo.txt
set lineNr=0
:while1
for /f "usebackq delims=" %%i in (`more +%lineNr% %LoggingFile%`) DO (
echo %%i
set /a lineNr+=1
REM Have an appropriate stop condition here by checking i
)
goto :while1
A command prompt way of doing it.
FileMon is a free stand alone tool that can detect all kinds of file access. You can filter out any unwanted. It does not show you the data that has actually changed though.
I second "tail -f" in cygwin. I assume that Tail for Win32 will accomplish the same thing.
Tail for Win32
I did a tiny viewer by my own:
https://github.com/enexusde/Delphi/wiki/TinyLog

Resources