Introduction
I am, by no means, a professional singer, nor a professional voice coach, but I do have a certain kind of OCD affinity for singing, and I have studied with opera, jazz and regular (for lack of a better word) voice coaches, so I figured I would share a brief synopsis of what I know so far.
Philosophy:
No one can teach you how to sing. You can only teach yourself, with a few hints from others. If you can effectively and comfortably sing a song without any ill effects, carry on.
By that same token, no one can teach you how to breathe either ;-) You already instinctively know how to breathe, or else you would not be reading this right now (wink).
This natural, instinctive ability to breathe and sing is evidenced by the fact that a small baby can cry all day (some of us know this all too well) without losing their voice, and each and every one of us, no matter what age, would surely and naturally hit an incredible high note if were were to fall off a cliff!
That being said, there are some nice to know nuances that can help you steer clear of the typical under-breath that comes from a lack of confidence, or over-breath that comes from nerves.
As for vocal position, i.e. to go through the range from chest to mixed to head voice, that is a bit more complicated, but, for the most part, one learns this by trying to follow along with scales in a safe place ('safe' meaning, away from prying ears, so that you can experiment without constraints), and continually building an internal compass for how to navigate through notes, and, ultimately songs.
Much like scales, each song is, indeed, a journey that one has to navigate through.
As you continue to grow, maintain a personal, unified theory of singing, in terms of the fundamentals to be mindful of. As you add more songs requiring different skills to perform, you should never have to ditch everything you know, but you should never beat your head against the wall based on what you think you know either. Even the great Beniamino Gigli, when asked when he finally mastered the voice responded: "I have not" (in Italian, of course). Your task as a singer is to keep developing an understanding and a mental model that works across every song, without being unrealistic or disappointed in *your voice*.
Fundamentals:
Smile, as the single most important thing you can do to make sure that you are in the right physiological position to sing. A harder note should prompt a stronger smile. Really good singers are able to create the interior effects of a pronounced smile without having to actually smile on the exterior, so I would not necessarily look for evidence of this advice on the faces of your favorite singers, but, rather, would invite you to try it and see if the difference in head space becomes evident, after which time you might be able to make the association of a smile and its effects, and then figure out the effects without the smile.
In operatic singing, this 'smile effect' is called 'covering the song'.
Always sing in mixed mode, meaning: Direct your voice towards your palate from the back of your throat. Avoid trying to force resonance out of just the head or chest. If a key is too high or too low, then modify the song, because you cannot modify your voice into an unnatural key. This technique is transparent in a trained singer, but you will clearly hear this kind of ill-advised forcing of head or chest space from your local karaoke scene or cover bands, or from singers that should have retired long ago.
Understand proper breath control. More appropriately, understand that the breath powers the voice. In some ways, our 'voice' (i.e. vocal cords) are doing little more than flapping in the wind ;-) You need to take in enough breath, and you need to let it out with enough consistency to allow the vibrations to do their thing. There is no additional engineering required, and any technique that attempts to over-engineer this phenomenon (e.g. sing from your heels, sing through the top of your head) is more likely to lead to misguided dynamics than the simple zen of 'doing without doing' by letting your body work as designed.
You already know how to handle your breath when you are talking, because our brains have an incredible ability to maintain the right level of air support for conversation, but as soon as you attempt a song that requires a bit of unnatural planning (e.g. Across the Universe from the Beatles) you will go beyond this natural ability, and if you don't have a few rules of thumb to follow, you may not fare too well.
For operatic singing, constrained full breaths are the norm, but there are certain high notes that call for singing on a near-empty lung, as you want to have a small thread of air at a very high velocity to hit notes in the high (tenor) A, B, C region. This is where I think trained opera singers defy imagination, because they are doing something that is completely counter-intuitive and unnatural to produce incredible notes.
If you go home and try to approximate this without understanding the physicality of what they are doing, you will hurt yourself, and, perhaps, prompt your neighbors to call the police. But if you were to try and swell into an approximation (i.e. from quite to loud), you might start to develop an understanding, but your neighbors might still call the police. A rule of thumb here is: never try to shout your way into a note.
Strengthening the voice is a separate concern from singing. It is like training in the gym vs playing a sport. A football player does not endeavor to do squats while he is playing the game, but he benefits from them nonetheless. In terms of strengthening the voice, outside of actually singing, I’ve come to rely on these four: (1) Core exercises through the empty lung, which is different than core in the gym. You can do all the sit ups you want, but this will never increase your ability to squeeze. Try this: breath out until you cannot breath out any further, and then breath out as if you were trying to blow out a candle. You will feel a potentially unfamiliar squeeze. It is the same squeeze that your body does naturally when you sneeze, but because you take in a full breath just prior to sneezing, you never feel the kind of maximum, interior squeeze that this kind of empty lung exercise invokes. You should still do core in the gym, for overall support, but it is ***ONLY*** this squeeze that is going to effect your singing. (2) 1/4 second and 1/2 second exercises. This is a hard one to describe in writing, but here goes. If you breath out until you are just about of air, which will naturally drop your voice box a bit, then let your vocal cords get into the same position they would be in if you were holding your breath and then try to squeak, for lack of a better word, in that exact position, then you will have achieved a 1/4 second. The 'squeak' is not meant to be high pitch, but, rather, is meant to be whatever comes out in the position described. Changing pitch comes later, but is not the essential point of this exercise. If you master this, and then move on to more than just a pulse, i.e. a longer note, then you will have achieved a 1/2 second, where 1/2 second could be more like a full second, but you don't want to go much longer than that, so as not to damage your vocal cords. To that end, remember that this is an exercise, not a position to learn for singing, as surely as doing squats on the football field would be ill-advised. (3) Power Scales. You can look this up on the internet, and I am sure that you will find videos and scales for your voice type. (4) Power Falsetto Notes. This is ***NOT*** scales, but, more like hitting an progressively higher sequence of very high notes (i.e. that require one to sing in falsetto) for as long as you can hold the note (say, 5 to 20 seconds). Again, this would necessarily be for singing, unless you want to cover the Bee Gees, but is more about building strength and flexibility to help with mixed mode singing, as well as give you the foundation to hit and hold high notes if/when you need them.
There are a whole bunch of other fundamentals pertaining to vibrato, etc, but there are plenty of great videos and books out there, and my intention is not to write a book here ;-) Just be weary of the books that spend the first 5 out of 15 chapters extolling the virtues of proper hydration, nutrition and sleep. I view authors of such books to be charlatans of sorts, trying to achieve a certain page count to convey a sense of comprehensiveness and authority that, in reality, probably amounts to no more than this blog.
Tactical Stuff:
Learn the difference between beneficial vs detrimental vocal thrashing, and try to limit thrashing to the evening hours, so you can rest thereafter and let your mind work it out. Thrashing is when you are trying to figure out how to sing a song that should be achievable, but has been problematic. Sometimes you just have to keep trying a song or a section of a song over and over again to figure it out, and this can lead to a certain kind of abuse of your voice, which you can embrace, so long as you learn to differentiate the good kind vs the bad kind of abuse. With that in mind, you should always try to sing songs that are out of reach, not necessarily so you can eventually perform them, but more so to develop new skills while trying to cope with them, which can then be applied to the songs that are attainable.
Develop your own internal monitor for singing, so that you just do your thing, no matter what. In other words, whether you find yourself with a crappy quiet or crappy loud sound system, you use the same vocal position and support vs trying to modulate on the fly. For this reason, avoid singing in the shower or the car, because either one will impair this internal monitor and lead to bad habits - you might find yourself modifying your style based on the over-feedback of the shower or under-feedback of the car. Best to practice in a room with moderate acoustic feedback and master this in that kind of environment.
Do not try to match the timbre of another singer’s voice. Go for the note, not the tone. If you can cover Chris Cornell in his key, great, just beware of covering his growl, because that stems from a combination of his vocal qualities and bad choices - he had nodules several times, and, in my opinion, could barely sing before he committed suicide.
Every song has a vocal path, and, outside of memorizing the lyrics, you have to memorize your vocal through a song, so that you have the right amount of breath support, tension, position as you go. It is not as complicated as it sounds.
Cheers!
Sunday, November 11, 2018
Wednesday, November 7, 2018
The Great Debate
This is a great debate.
Worth a listen in its entirety.
The motion was “what you call political correctness, I call progress”.
It did not remain narrowly focused on that topic, since, in reality, the topic itself is not narrowly defined, due to its conflation with free speech vs social justice vs other.
I cannot say that either team ‘won’, except to say that the related topic of identity politics was the most frequented side topic.
It goes something like this:
Individuals are lumped into groups by those in power, for the primary purpose of denying them their rights on a stereotypical basis.
Individuals whose rights are denied band together into groups to secure their rights.
The narrative for members within groups then becomes one of struggle between groups, along the lines of oppressed and oppressor.
This dynamic causes a reaction in kind by those in power, which further entrenches group identification and leads to polarization and the populist movements we see today, if you buy Jordan Peterson’s argument.
In this mode, the oppressed become intolerant, and even though they maintain a legitimate complaint of social injustice, they start to exhibit oppressive traits as well.
This intolerance leads to political correctness, and though one can argue that much of what political correctness is meant to suppress should legitimately be suppressed (derogatory terms, inflammatory ideas, etc), it can also lead to a suppression of ideas and dialogue, for fear of being politically incorrect.
The notion that controlling what people say will change how they think is ridiculous, and only foments a kind of quiet anger in those that feel they are being censored.
Enter Trump.
He unapologetically says what he thinks, even if it is not politically correct, and his popularity rises with each episode.
Why?
Because he says what a lot of people feel.
My contention is that he could say what almost everyone feels on the higher end of the moral spectrum by appealing to our better, common traits, i.e. be the ‘uniter in chief’ vs the ‘divider in chief’. That being said, Trump is tapping into a current that was already there, right or wrong, which has been exacerbated by identity politics.
I don’t think that identity politics and political correctness are really working for us, do you?
https://youtu.be/GxYimeaoea0
Sunday, October 28, 2018
Don't Unfriend Anyone
Many of my friends have un-friended [former] friends over this ever increasing divide between conservatives and liberals, or, perhaps, 'Trumps' and 'anti-Trumps'. I have not unfriended a single person, nor lost a single friend over this divide, not because I am not concerned over the divergence in points of view or interpretation of facts, but because I fully embrace the idea that it is more complicated than a two-sided arguent. One could argue, "no, it is not more complicated than that; you are either on the right side of history and today, or you are not". We haven't reached that point yet, and I pray that we never will. Right now, we are locked into the kind of gridlock that our founding fathers contemplated in our system of government, i.e. to ensure that only the very best legislation passes, with the caveat that we may not reach the kind of legislative gridlock until after the mid-term elections. In the meantime, while I uniformly disapprove of Trump's behavior, and the implementation of some of his policies, I do not uniformly disapprove of all of this policies. Therefore, I do not uniformly disapprove of anyone's support for Trump. I do wish that people - all people, conservatives and liberals - would be more careful and contemplative in thier thinking and their accounting of the facts, but I also wish that we would hold each other to account in a more embracing way, because I think people tend to calcify into unreasonable positions when they feel like they are being attacked. This is the number one reason I have not unfriended anyone, nor consider any friend a not-friend just based on their political views. My friends need to know that I am their friend, and that I understand their calculus in their political views. They also need to know that I will hold them to account on their thinking and their arguments, not becuase I inherently think they are wrong and I am right, but because I inherently want to know why they think the way they do, and am open to modifying my point of view with theirs, and I expect them to do the same when there is merit. This philosophy, I think, will go much further towards a better 'third option' than this current, two-sided trend will ever do.
Thursday, October 25, 2018
American Exceptionalism and Trump?
I’ve seen a few posts and comments on American Exceptionalism, and how this is misunderstood by one group or another, or how it is embodied by one politician or another. To the extent that anyone believes that American Exceptionalism is derived from the genius of our Constitution and its framers, I believe the root of this concept is best encapsulated in the Federalist Papers, and, further, would go so far as to challenge anyone who says they have command of this concept to frame it along the doctrines laid out in the constituent articles. The papers were published in 1787 by James Madison, Alexander Hamilton and John Jay, all of whom were intellectual giants, especially in relation to today’s politicians, and all of whom were making the case for the constitution of a union, along with a caution against disunion, either as 13 states or 3 or 4 confederations. If you endeavor to read them, you might be surprised by the similarities of the challenges of our day to the challenges of their day. In short, we have not evolved all that much philosophically over the past 200+ years. You might reach the same conclusion about the last 2,000+ years if you read Plato’s dialogues. I will leave it to you to read the papers, or not, and discern American Exceptionalism, or not, at least insofar as you can discern it from the papers, but I can tell you in advance that Trump’s behavior does not embody the spirit or the substance of American Exceptionalism in its unifying, mutually inclusive and anti-factious form. When people invoke the concept of American Exceptionalism alongside any argument that Trump exemplifies it, I take exception (wink). I would much rather someone simply say, “he is effective and he gets results”, without trying to equate him with the more noble principles in American Exceptionalism, especially pluralism and representation.
Thursday, October 18, 2018
Immigration
Immigration has a mostly favorable impact on the US. Quoting an article from TheBalance.com, “Immigrants have driven two-thirds of U.S. economic growth since 2011. They founded 30 percent U.S. firms, including 50 percent of startups valued at over $1 billion.” The ‘immigrant’ moniker here encompasses both legal and illegal immigrants, but we can probably guess that the founder of the $1 billion startup is mostly likely here legally (wink). Against the back drop of an accelerating deficit, thanks to the so-called fiscal conservatives on the right, immigration should actually be embraced by most Americans, because it injects more young people into the economy, thereby widening the base that supports Social Security and Medicare. In fact, nearly half of the of the 8 million illegal immigrants that are in the workforce pay Social Security payroll taxes, even though they are not eligible for Social Security benefits. This may or may not be a convincing argument, partly because statistics can be interpreted in many different ways, and even if the interpretation is correct, someone born and bred in the U.S. who is struggling to get by would find the notion of allowing immigrations to flow into the country and complete for jobs disconcerting. We have an immigration policy, so the fact that 1000s of migrants head to the U.S. border, in caravans or not, is not necessarily a bad thing, but the tone def and prototypical liberal argument that ignores the difference between bona fide asylum seekers and economic migrants helps me to better understand why Trump enjoys so much support, especially on the immigrant front, despite some of his controversial policy decisions. The optics of Mexico allowing 4,000 migrants to pass through to the US border are pretty bad, even if the real implications are not, given the estimated 400,000 to 800,000 illegal entries a year. Therefore, to me, the optics of Trump’s [over]reaction are pretty good. In my opinion, if the home countries and Mexico are going to facilitate this level of mass migration, thereby overrunning our borders and driving up the related administrative costs of processing immigrants, then we should cut aid to these countries and recoup those costs. One could argue that the second order effect of cutting aid and otherwise disengaging from Central and South America will only exacerbate the situation and accelerate migration to the U.S., but I, for one, would rather not be held hostage to that notion. I would rather we take control of our border, even if it means deploying our military, and then figure out how to deal with the situation more holistically later.
REF https://www.thebalance.com/how-immigration-impacts-the-economy-4125413
REF https://www.thebalance.com/how-immigration-impacts-the-economy-4125413
Saturday, October 6, 2018
Andrew Yang
I don’t think that someone like Andrew Yang would get enough traction in a near-future Presidential election, but I do think we need to start grappling with the challenges and solutions that he discusses. I’ve been hearing about massive manufacturing job losses in China (yes, China) due to automation, and though we attribute offshoring as a major contributing factor in the loss manufacturing jobs here in the US, which it has been, even if we reversed this tide, we would still be facing major job losses to automation, and, now, with AI, the displacement of workers is going to occur in more areas - Call Centers, Retail, Transportation (autonomous, self-driving trucks). But first, we will need to disabuse ourselves of the labels that drive our thinking into Capitalism vs Socialism, Rich vs Poor and Politically Elite vs Politically Disenfranchised, so that we can consider ideas for a better future, without getting mired in the past. Andrew’s big ideas: Universal Basic Income, Universal Healthcare and a redefinition of GDP that more accurately reflects the health of the nation, especially as it relates to the difference in well being between Wall Street and Main Street. These are, indeed, big ideas, but, for anyone who has looked at our evolving world and doubted that things are just going to work themselves out, perhaps the process of embracing big ideas should be initiated with all deliberate speed?
REF https://youtu.be/qkH0xGUgR0c
REF https://youtu.be/qkH0xGUgR0c
Thursday, September 27, 2018
The Single Event
I am always very aware of my interactions with Nicholas, mainly because I know that events averaged over my lifetime to date are much smaller than the same events averaged over his lifetime to date. I think this is the fundamental calculus that so many parents neglect. In some respects, it is quite unfair to parents that a single, negative event might get burned in to a child’s memory and hold sway over their recollection more than the aggregate of all the parental sacrifices and positive events. It is of little use to complain about this fact of life, because it is, after all, a fact of life. Taken out of the parental domain, this same phenomenon applies to other events in a child’s life - getting bullied, being ridiculed, being ignored, etc. This is, perhaps, why so many parents instinctively know that over caution is warranted when comes to their child’s experiences in the world, even as they forget that the same over caution needs to be applied to their child’s experiences with them. Of course, parents do the best they can under the circumstances they find themselves in, and sometimes these circumstances can be overwhelming, so, as children, we have to evaluate the single events that we hold on to as defining characteristics of the parenthood we were subjected to. This all boils down to awareness on both sides of the parent-child high-wire. We need to teach ourselves to be aware of what we do, and we need to teach our children to be aware of why we do.
Tuesday, September 25, 2018
Intermittent Differences, Enduring Similarities
I’ve seen a few comments expressing sadness about our divisions and foretelling the end of our great nation. I am not so sure, and here is why: Fake news may cause those on the polar extremes to outsource the determination of what is real to their polarized leaders, but for those of us in the middle, it should make us more independent minded and better fact checkers. Social Media may short circuit to personal attacks for those whose extreme views cannot tolerate questioning, but for those of us in the middle, it should improve our debating skills and help us to maintain our perspective on our intermittent differences and enduring similarities. Volatile issues might seem to further divide us, but such issues also divide the divided, and, like water molecules, we become more fluid. There are times when I wholeheartedly agree with and assessment from one friend that a different friend would find the patently offensive, and vice versa. In short, throughout all of these polar extremes, the middle gains momentum. We have less strife than we did during the Civil War, or the Civil Rights Movement, or the Vietnam War. We are just flexing the margins and improving ourselves to move forward with a more unified understanding of each other and the world. We should not feel grateful for this particular process, because there are better ways to achieve the same objective. We should not feel fearful either, because it is the same objective after all.
Sunday, August 19, 2018
Presidential
In my opinion, Michael Avenatti has ridden Stormy Daniels further than most of her co-stars ;-) Now he is running for President, and, aside from having a platform based on 'The Truth', one of his tenants is that "we have to fight fire with fire". That might be okay, so long as the adherance to 'The Truth' does not give way to firefightning, but, again, in my opinion, I think we really need a leader who can offer love over hate, inclusiveness over identity, understanding over ignorance, policies over politics and, ultimately, inspiration over instigation.
Climate Change
It occurs to me that we may potentially cure cancer, an immense and complex endeavor, before we halt or reverse climate change, which is an immense and complex endeavor as well, but only because too many of us refuse to embrace the evidence, or refuse to ‘see’ what is happening around us, or lack the moral imperative to conserve the world we live in, even if the evidence is disputable. I am going to take a good hard look at myself in this regard, because it seems to me that if we do leave a livable world to our children and grandchildren, it will start with personal choices that live outside of regulation and incentives, as a leading indicator for a collective awakening.
Saturday, June 30, 2018
Immigration Rallies
I can see how the average Trump supporter would view today's rallies as the product of uninformed liberals calling for open borders and lawlessness that will eventually lead to the demise of our country as we are overrun by people fleeing dysfunctional countries south of the border who will eventually deplete our financial and social reserves. I can see how the average anti-Trump supporter would view the events leading up to today's rallies as the product of uninformed conservatives forgetting what makes this country great, up to and including how the struggle to make it in America contributes to our very fabric, GDP and overall wealth and well being. To me, both points of view are correct and incorrect. We can't be completely open and we can't be completely closed. That being said, I think the more essential leit motif of today's rallies is that, either way, we cannot afford to lose our humanity as we implement the policy at hand. Whether we are open or closed, we have to remain uniquely 'American' in our ways.
Saturday, June 2, 2018
Suburban Shrimp Scampi
I think I’ve stumbled on to a near perfect Shrimp Scampi recipe for the average suburbanite, who, additionally, likes to avoid garlic and onions.
Here are the ingredients:
2 pounds of peeled and deveined medium shrimp. Of course, if you are a big fan of manual labor, you can peel and devein them yourself, but I would encourage you to research both comparative advantage and opportunity cost first.
2 cups of Pinot Grigio. There is no need for presumption here. Just buy any brand that comes from the Venice, Italy area in a large, 1.5L bottle for less than $10.
4 table spoons of salted butter
1/2 large (6g) Knorr chicken bouillon cube. Of course, you can use any brand.
1 cup of Italian parsley. This would be just the tops. When I say 1 cup, I mean if you lightly pat the leaves down. If you insist on pushing the leaves down with your foot, I am sure you could compress an entire bushel in a cup, but this is not my intent.
The juice from 1/2 lemon
In a large, wide bottomed pot over low to medium heat, combine the Pinot Grigio, lemon juice, butter, parsley and bouillon cube, and then let simmer until the very nearly all of the liquid has evaporated. Imagine you have an untreated urinary tract infection that has been festering for a few weeks, and then you take the darkest, thickest piss you’ve ever seen. When the ingredients in question here approximate that color and consistency, you are ready to move to the next step (and go to the ER).
Most recipes counsel you to cook shrimp over medium to high heat for 6 minutes, but, unless you have a centrifuge that you can use to drain the water from your shrimp, I find that it is better to simmer the shrimp, uncovered, for a longer period of time.
Thus, add the shrimp to the reduction and simmer over low-to-medium heat (i.e. the same level you used to create the reduction) uncovered for about 20 minutes or until the shrimp scampi has a reasonable amount of liquid, but not too much.
Enjoy :-)
Tuesday, May 29, 2018
Cracks In The Paint
When I worked at Boeing Helicopters, I recall talking to an Engineer on the shop floor about a special paint that they used on the CH-47 (Chinook). The paint would bond to the underlying frame at a molecular level, to the point where a fracture deep within the frame would manifest itself as a crack in the paint, thereby providing all those involved with a clear indication that the frame needed repair. Rosanne Barr is the crack in the paint. We should be thankful for her signal, even as we detest her.
Wednesday, May 23, 2018
Truth
If one endeavors to speak the truth, then one must know what the truth is, and this goes far beyond the simple truths. It is one thing to know if you are lying by commission or omission. It is another thing to understand how you feel, recognize a situation for what it is, and speak the truth without undue friction. Whether you are dealing with a relative, a friend or a coworker, and whether you are grappling with how you feel about them or how they feel about you, you might not really know what the truth (your truth) is. And even if you do, is the ugly truth better than a polite lie that might smooth things over? I’ve seen depictions of how a succession of truths turns out to be disastrous (Everybody Loves Raymond) as well as depictions of how a succession of lies turns out to be equally disastrous (Seinfeld). To the extent that it is not always practical to prioritize authenticity over expediency, I wonder if it might be better to say nothing at all, rather than to fabricate an insidious lie or deliver an explosive truth. With regard to this particular question, I would accept either an honest or a polite answer, and that’s not the truth.
x
Tuesday, May 15, 2018
Salesforce: Apex: Generate from WSDL
Problem
.
When trying to generate Apex from a WSDL in Salesforce, you have to do a few things to make the WSDL suitable for use with the OOTB 'Generate from WSDL' option. It is possible that the Open Source WSDL2Apex Generator (here) does not require similar preprocessing, but, as of this writing, I have not tried it, so I do not know. In this post, I am only going to focus on the two actions that I had to take to get a WSDL into a suitable form, but I am relatively certain that this is only a small subset of what one might have to do along the spectrum of WSDLs..
Solution
.
Step 1: Inline the Imports
.
Let's say you have a WSDL that looks something like this:
.
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="ServiceName" targetNamespace="http://[domain]/[namespace]" xmlns:tns="http://[domain]/[namespace]" [...etc...]>
<types>
<xsd:schema>
<xsd:import schemaLocation="https://[domain]/[schema]" namespace="http://[domain]/[namespace]"/>
</xsd:schema>
</types>
<message name="SomeMessage">
<part name="parameters" element="tns:SomeMessage"/>
</message>
<portType name="ServiceName">
<operation name="SomeMessage">
<input message="tns:SomeMessage" wsam:Action="http://[domain]/[namespace]/[method]"/>
<output message="tns:SomeMessageResponse" wsam:Action="http://[domain]/[namespace]/[method]"/>
<fault name="ServiceException" message="tns:ServiceException" wsam:Action="http://[domain]/[namespace]/[method]/fault/ServiceException"/>
</operation>
<xs:complexType name="ServiceException">
<xs:sequence>
<xs:element name="errorCode" type="xs:int"/>
<xs:element name="message" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
[...etc...]
</definitions>
<definitions name="ServiceName" targetNamespace="http://[domain]/[namespace]" xmlns:tns="http://[domain]/[namespace]" [...etc...]>
<types>
<xsd:schema>
<xsd:import schemaLocation="https://[domain]/[schema]" namespace="http://[domain]/[namespace]"/>
</xsd:schema>
</types>
<message name="SomeMessage">
<part name="parameters" element="tns:SomeMessage"/>
</message>
<portType name="ServiceName">
<operation name="SomeMessage">
<input message="tns:SomeMessage" wsam:Action="http://[domain]/[namespace]/[method]"/>
<output message="tns:SomeMessageResponse" wsam:Action="http://[domain]/[namespace]/[method]"/>
<fault name="ServiceException" message="tns:ServiceException" wsam:Action="http://[domain]/[namespace]/[method]/fault/ServiceException"/>
</operation>
<xs:complexType name="ServiceException">
<xs:sequence>
<xs:element name="errorCode" type="xs:int"/>
<xs:element name="message" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
[...etc...]
</definitions>
.
The 'xsd:import' is not supported, so you have to actually inline the related schema into this WSDL, which we will refer to as the 'Consolidated_WSDL', for clarity.
.
Let's say that related schema looks something like this:
.
<?xml version='1.0' encoding='UTF-8'?><xs:schema xmlns:tns="http://[domain]/[namespace_1]" version="1.0" targetNamespace="http://[domain]/[namespace_1]">
<xs:import namespace="http://[domain]/[namespace_2" schemaLocation="https://[domain]/[namespace_2]"/>
<xs:import namespace="http://[domain]/[namespace_3" schemaLocation="https://[domain]/[namespace_3]"/>
<xs:element name="SomeException" type="tns:SomeException]"/>
<xs:element name="SomeService" type="tns:SomeService"/>
[...etc...]
</xs:schema>
.
You would inline this schema by replacing the entire <xsd:import> block in the Consolidated_WSDL with just the <schema> block from this file, as follows, in blue:
.
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="ServiceName" targetNamespace="http://[domain]/[namespace]" xmlns:tns="http://[domain]/[namespace]" [...etc...]>
<types>
<xs:schema xmlns:tns="http://[domain]/[namespace_1]" version="1.0" targetNamespace="http://[domain]/[namespace_1]">
<xs:import namespace="http://[domain]/[namespace_2" schemaLocation="https://[domain]/[namespace_2]"/>
<xs:import namespace="http://[domain]/[namespace_3" schemaLocation="https://[domain]/[namespace_3]"/>
<xs:element name="SomeException" type="tns:SomeException]"/>
<xs:element name="SomeService" type="tns:SomeService"/>
[...etc...]
</xs:schema> </types>
<message name="SomeMessage">
<part name="parameters" element="tns:SomeMessage"/>
</message>
<portType name="ServiceName">
<operation name="SomeMessage">
<input message="tns:SomeMessage" wsam:Action="http://[domain]/[namespace]/[method]"/>
<output message="tns:SomeMessageResponse" wsam:Action="http://[domain]/[namespace]/[method]"/>
<fault name="ServiceException" message="tns:ServiceException" wsam:Action="http://[domain]/[namespace]/[method]/fault/ServiceException"/>
</operation>
<xs:complexType name="ServiceException">
<xs:sequence>
<xs:element name="errorCode" type="xs:int"/>
<xs:element name="message" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
[...etc...]
</definitions>
<definitions name="ServiceName" targetNamespace="http://[domain]/[namespace]" xmlns:tns="http://[domain]/[namespace]" [...etc...]>
<types>
<xs:schema xmlns:tns="http://[domain]/[namespace_1]" version="1.0" targetNamespace="http://[domain]/[namespace_1]">
<xs:import namespace="http://[domain]/[namespace_2" schemaLocation="https://[domain]/[namespace_2]"/>
<xs:import namespace="http://[domain]/[namespace_3" schemaLocation="https://[domain]/[namespace_3]"/>
<xs:element name="SomeException" type="tns:SomeException]"/>
<xs:element name="SomeService" type="tns:SomeService"/>
[...etc...]
</xs:schema> </types>
<message name="SomeMessage">
<part name="parameters" element="tns:SomeMessage"/>
</message>
<portType name="ServiceName">
<operation name="SomeMessage">
<input message="tns:SomeMessage" wsam:Action="http://[domain]/[namespace]/[method]"/>
<output message="tns:SomeMessageResponse" wsam:Action="http://[domain]/[namespace]/[method]"/>
<fault name="ServiceException" message="tns:ServiceException" wsam:Action="http://[domain]/[namespace]/[method]/fault/ServiceException"/>
</operation>
<xs:complexType name="ServiceException">
<xs:sequence>
<xs:element name="errorCode" type="xs:int"/>
<xs:element name="message" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
[...etc...]
</definitions>
.
You may have noticed the additional 'xs:import' elements in the schema that we just inlined. These would have to be inlined as well. You would simply navigate to the schema location for each import, and then copy-paste the <schema> block for each import as peers to the schema we just copy-pasted, and remove the import elements, as follows, with the new schemas in bold-blue, and the removed import elements in strikethrough (e.g. strikethrough):
.
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="ServiceName" targetNamespace="http://[domain]/[namespace]" xmlns:tns="http://[domain]/[namespace]" [...etc...]>
<types>
<xs:schema xmlns:tns="http://[domain]/[namespace_1]" version="1.0" targetNamespace="http://[domain]/[namespace_1]">
<xs:import namespace="http://[domain]/[namespace_2" schemaLocation="https://[domain]/[namespace_2]"/>
<xs:import namespace="http://[domain]/[namespace_3" schemaLocation="https://[domain]/[namespace_3]"/>
<xs:element name="SomeException" type="tns:SomeException]"/>
<xs:element name="SomeService" type="tns:SomeService"/>
[...etc...]
</xs:schema> <xs:schema xmlns:tns="http://[domain]/[namespace_2]" version="1.0" targetNamespace="http://[domain]/[namespace_2]">
[...etc...]
</xs:schema>
<definitions name="ServiceName" targetNamespace="http://[domain]/[namespace]" xmlns:tns="http://[domain]/[namespace]" [...etc...]>
<types>
<xs:schema xmlns:tns="http://[domain]/[namespace_1]" version="1.0" targetNamespace="http://[domain]/[namespace_1]">
<xs:element name="SomeException" type="tns:SomeException]"/>
<xs:element name="SomeService" type="tns:SomeService"/>
[...etc...]
</xs:schema> <xs:schema xmlns:tns="http://[domain]/[namespace_2]" version="1.0" targetNamespace="http://[domain]/[namespace_2]">
[...etc...]
</xs:schema>
<xs:schema xmlns:tns="http://[domain]/[namespace_3]" version="1.0" targetNamespace="http://[domain]/[namespace_3]">
[...etc...]
</xs:schema>
[...etc...]
</xs:schema>
</types>
<message name="SomeMessage">
<part name="parameters" element="tns:SomeMessage"/>
</message>
<portType name="ServiceName">
<operation name="SomeMessage">
<input message="tns:SomeMessage" wsam:Action="http://[domain]/[namespace]/[method]"/>
<output message="tns:SomeMessageResponse" wsam:Action="http://[domain]/[namespace]/[method]"/>
<fault name="ServiceException" message="tns:ServiceException" wsam:Action="http://[domain]/[namespace]/[method]/fault/ServiceException"/>
</operation>
<xs:complexType name="ServiceException">
<xs:sequence>
<xs:element name="errorCode" type="xs:int"/>
<xs:element name="message" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
[...etc...]
</definitions>
<message name="SomeMessage">
<part name="parameters" element="tns:SomeMessage"/>
</message>
<portType name="ServiceName">
<operation name="SomeMessage">
<input message="tns:SomeMessage" wsam:Action="http://[domain]/[namespace]/[method]"/>
<output message="tns:SomeMessageResponse" wsam:Action="http://[domain]/[namespace]/[method]"/>
<fault name="ServiceException" message="tns:ServiceException" wsam:Action="http://[domain]/[namespace]/[method]/fault/ServiceException"/>
</operation>
<xs:complexType name="ServiceException">
<xs:sequence>
<xs:element name="errorCode" type="xs:int"/>
<xs:element name="message" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
[...etc...]
</definitions>
.
You need not get trapped in recursion during this process ;-)
.
If, for example, the schema for namespace_3 imported namespace_2, then you can rely on the already copy-pasted namespace_2 in the Consolidated_WSDL.
.
Step 2: Take Exception with 'Exception'
.
The Apex compiler does not like it when a class ends with the keyword 'Exception' unless it extends the Exception Class. In the example above, you will notice the 'ServiceException' complex type, element, fault, etc. This would need to be renamed in an identifiable way, so that you can locate the renamed artifacts in the generated Apex later (see below). I simply appeneded 'WSDL' to the end of all such 'Exception' references in a rather large WSDL, taking care to replace "ServiceException" with "ServiceExceptionWSDL" and "tns:ServiceException" with "tns:ServiceExceptionWSDL", etc. Take care to be very specific about your find-and-replace operations, so as not to accidentially replace an 'Exception' reference in a URL. I suggest you use fully double-quoted strings in your find-and-replace logic, so that you avoid URLs altogether.
.
The final Consolidated_WSDL would look something like this:
.
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="ServiceName" targetNamespace="http://[domain]/[namespace]" xmlns:tns="http://[domain]/[namespace]" [...etc...]>
<types>
<xs:schema xmlns:tns="http://[domain]/[namespace_1]" version="1.0" targetNamespace="http://[domain]/[namespace_1]">
<xs:element name="SomeExceptionWSDL" type="tns:SomeExceptionWSDL]"/>
<xs:element name="SomeService" type="tns:SomeService"/>
[...etc...]
</xs:schema>
<xs:schema xmlns:tns="http://[domain]/[namespace_2]" version="1.0" targetNamespace="http://[domain]/[namespace_2]">
[...etc...]
</xs:schema>
<definitions name="ServiceName" targetNamespace="http://[domain]/[namespace]" xmlns:tns="http://[domain]/[namespace]" [...etc...]>
<types>
<xs:schema xmlns:tns="http://[domain]/[namespace_1]" version="1.0" targetNamespace="http://[domain]/[namespace_1]">
<xs:element name="SomeExceptionWSDL" type="tns:SomeExceptionWSDL]"/>
<xs:element name="SomeService" type="tns:SomeService"/>
[...etc...]
</xs:schema>
<xs:schema xmlns:tns="http://[domain]/[namespace_2]" version="1.0" targetNamespace="http://[domain]/[namespace_2]">
[...etc...]
</xs:schema>
<xs:schema xmlns:tns="http://[domain]/[namespace_3]" version="1.0" targetNamespace="http://[domain]/[namespace_3]">
[...etc...]
</xs:schema>
[...etc...]
</xs:schema>
</types>
<message name="SomeMessage">
<part name="parameters" element="tns:SomeMessage"/>
</message>
<portType name="ServiceName">
<operation name="SomeMessage">
<input message="tns:SomeMessage" wsam:Action="http://[domain]/[namespace]/[method]"/>
<output message="tns:SomeMessageResponse" wsam:Action="http://[domain]/[namespace]/[method]"/>
<fault name="ServiceExceptionWSDL" message="tns:ServiceExceptionWSDL" wsam:Action="http://[domain]/[namespace]/[method]/fault/ServiceException"/>
</operation>
<xs:complexType name="ServiceExceptionWSDL">
<xs:sequence>
<xs:element name="errorCode" type="xs:int"/>
<xs:element name="message" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
[...etc...]
</definitions>
.
<message name="SomeMessage">
<part name="parameters" element="tns:SomeMessage"/>
</message>
<portType name="ServiceName">
<operation name="SomeMessage">
<input message="tns:SomeMessage" wsam:Action="http://[domain]/[namespace]/[method]"/>
<output message="tns:SomeMessageResponse" wsam:Action="http://[domain]/[namespace]/[method]"/>
<fault name="ServiceExceptionWSDL" message="tns:ServiceExceptionWSDL" wsam:Action="http://[domain]/[namespace]/[method]/fault/ServiceException"/>
</operation>
<xs:complexType name="ServiceExceptionWSDL">
<xs:sequence>
<xs:element name="errorCode" type="xs:int"/>
<xs:element name="message" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
[...etc...]
</definitions>
.
Generate from WSDL
.
When you generate new Apex code from the WSDL, you will be given the opportunity choose the same Apex class name for all inlined namespaces, or name them differently. Whatever you do, I suggest you pick a short name or names, just based on my experience of rather lengthy names in the WSDL that got truncated when I just accepted the defaults.
.
After you generate the Apex, you will need to refactor any 'Exception' classes and references to back to the original name, so that the final Apex conforms with the service contract. In the example we've been using so far, the ServiceExeption complex type renamed to ServiceExceptionWSDL would result in an Apex class that looks something like this:
.
public Integer errorCode;
public String message;
[...etc...]
.
After you generate the Apex, you will need to refactor any 'Exception' classes and references to back to the original name, so that the final Apex conforms with the service contract. In the example we've been using so far, the ServiceExeption complex type renamed to ServiceExceptionWSDL would result in an Apex class that looks something like this:
.
public class ServiceExceptionWSDL {
public Integer errorCode;
public String message;
[...etc...]
public Integer errorCode;
public String message;
[...etc...]
}
.
You need only remove whatever suffix (or prefix, or whatever) you added to the name (in this case, 'WSDL') and have the class extend the 'Exception' interface, as follows:
.
public class ServiceException extends Exception {public Integer errorCode;
public String message;
[...etc...]
}
.
In my particular case, I replaced 100s of references to ServiceException with ServiceExceptionWSDL in my Consolidated_WSDL, but all of those references amounted to a single, generated Apex class, so the refactoring was easy. Your mileage may vary.
.
In my particular case, I replaced 100s of references to ServiceException with ServiceExceptionWSDL in my Consolidated_WSDL, but all of those references amounted to a single, generated Apex class, so the refactoring was easy. Your mileage may vary.
.
References
.
Mr. Brent Schreibfeder, a Salesforce colleague, who graciously helped me with my general lack of understanding of WSDL structure and the process to inline imports.
.
.
Monday, May 14, 2018
Run with What You Brung
Today I had an experience that reminded me of one of Tony the Tenor's sayings: "Run with what you brung". It was a phrase originally pertaining to race cars - i.e. however it shakes out on race day, just race it - but he ported it over to singing, and used it as a way to counter the ever-present feeling that a singer has when it comes time to perform - i.e. that they are sub-par and not ready. In other words, just get into performance mode and deliver, and just let the voice do what the voice will do. You can't control everything... but you can control your thoughts.
Mother’s Day 2018
We judge our mothers by what we can remember, so I am struck by the wealth of love and attention I never committed to memory, just by the wealth of love and attention I see Val give to Nicholas every day. I think to myself, “did I come into the world that way? was my first caress like that? was I that helpless baby that cried in the night? was my only salvation in my mother’s arms? was I that toddler who needed constant company and supervision? was the totality of my experience so totally influenced by my mother?” The answer is yes, but it seems that appreciating it is a generational thing. My love and gratitude for Val grows each day, but even more so for the Mothers in my life, on Mother’s Day.
Childhood Radius
Since I was in the Scranton area, I decided to visit my childhood home. This is where I lived until I was 4. I barely remember the outside of the house (though I am sure it has changed considerably over the years), and I vaguely remember the inside of the house, but I remember the yard and the immediate neighborhood like it was yesterday. I had an almost ‘Skinnerian’ childhood in Scranton, minus a close friend. As I drove to the house, I was struck by how everything leading up to a 2 block radius of it was completely unfamiliar to me. But that is how it is. We live in the space we occupy. It imprints upon us. Anything beyond that boundary escapes us. I wonder what escapes me here and now?
Saturday, May 5, 2018
Memorable Childhood Lessons
I recall having a childhood debate in 1981 with my good friend Robert. It was about Lindsey Buckingham's new song, 'Trouble'. My contention was that Lindsey's intro to the song consisted of him saying "doo a dee a fow" or some phonetic equivalent, whereas Rob quite rationally and correctly contended that Lindesy was saying "two, three, four". I can remember walking with him from my house to his house, cutting through my neighbor's yard, and him being almost exasperated that I would not concede his point. It is one of those memories that resurfaces every time I feel myself clinging to an idea too dogmatically, or looking down my nose at someone who is doing the same. If only I could hold all such memorable childhood lessons in-memory simultaneously. As it stands, I can only fit the really sentimental ones.
Tuesday, May 1, 2018
Simple One
I’ve been following a one meal per day routine for the past three months, and I am astounded by the adjustment, in terms of mental clarity, energy level and, what I call, spiritual calmness. Our conscious minds sit atop a system of mental and physical processes that precede our self-awareness and our illusion of self and other control. I think that when we minimize our lives and strip away all of the noise, we can better grasp how our motion through this river of life has more to do the current than anything else. To me, any habit or routine that helps us pause long enough to stop swimming and start floating is a worthwhile endeavor.
Subscribe to:
Posts (Atom)